起因
使用弹弹Play看番时字幕过大,大概长这样:
于是我便开始寻找解决办法
解决之路
首先,查看是不是弹弹Play的问题。 使用PotPlayer观看是这样:
显然是弹弹Play的问题,在尝试更换播放器内核等一系列操作后,仍然没有解决。于是,我打算更换字幕试试。
然鹅,虽然找到了字体正常的字幕,但是时间轴却和这个视频不对应...看来得尝试其他方法。
终于,在字幕设置的右下角发现了这个:
一查证,果然如此!但是用手一个一个地修改太浪费时间了,我立马想到python可以帮我。
使用python批量修改这些文件
- 需求:在每个字幕
(.ass)
文件开头一行加上[Script Info]
- 额外需求:以后遇到相似问题,小改代码还能接着用
所以,基本思路是:
- 获取文件路径
- 打开并修改文件
在此过程中,我遇到了一些问题和困难:
- 每个字幕文件名尽管遵循一定规则,但是不仅仅有数字(集数)上的差异,还有几个我找不出规律的字母。 其中的"E43C438E"
我打算使用正则表达式来解决这个问题,但是一搜,还是比较麻烦。最后还是在这篇文章的引导下,获取了所有符合要求的文件名。
from os import listdir
path0 = "你要搜的文件夹"
flist = listdir(path0) #使用listdir()函数获取所有的文件名,保存到名为flist的list变量里
flist_need = [] #存放所需的名字
for i in range(0, len(flist)): #遍历flist里面的所有项
extension = flist[i].split(".")[-1] #使用split()分割字符串,获取尾缀([-1])
if extension == "ass": #符合条件的尾缀
flist_need.append(flist[i]) #将符合条件的名称存入list
- 如何在开头添加字符串,而不是结尾
经过搜索,众多文章都提到了seek(0,0)
,这是让指针移动到指定位置的函数。前面的0代表位移量,后面的0代表从文件开头开始(1代表当前位置,2代表末尾位置)。
with open(path0 + flist_need[i], 'r+', encoding='utf-8') as f: #注意此处encoding,而且必须是'r+'
content = f.read()
f.seek(0,0) #必须得有,不然还是在尾巴那里加
f.write(insert_str + '\n' + content) #按照这个保存原本的内容->存入新内容的逻辑,应该不需要seek啊。但是去掉seek后会导致插在最后一行
- 编码问题
首先是报错,然后改成utf-8后,只有前两个文件成功了,但是后面的文件全乱码了...
用notepad++查看了一下编码格式,发现前两个文件格式是utf-8,后面两个就变成utf-16了。要解决这个问题,需要分开处理。
最终代码
from os import listdir
import os
insert_str = "[Script Info]" #要插入的内容
path0 = "你的文件夹路径"
flist = listdir(path0) #获取所有文件名称
flist_need = [] #存放所需的名字
for i in range(0, len(flist)):
extension = flist[i].split(".")[-1] #获取尾缀
if extension == "ass":
flist_need.append(flist[i]) #获取所有字幕名
#print(flist_need) #测试
for i in range(2):
with open(path0 + flist_need[i], 'r+', encoding='utf-8') as f: #如果是'a+'之类的,文件会只剩[Script Info]
content = f.read()
f.seek(0,0) #必须得有,不然还是在尾巴那里加
f.write(insert_str + '\n' + content)
for i in range(2,24):
with open(path0 + flist_need[i], 'r+', encoding='utf-16') as f:
content = f.read()
f.seek(0,0) #必须得有,不然还是在尾巴那里加
f.write(insert_str + '\n' + content)
总结
- 在
from os import listdir
里,listdir(文件夹路径)
可以获取该文件夹里面所有文件名(但是子文件夹里面的名字无法访问)。 - seek()函数可以帮我们指定指针指向的文件的位置。
seek(位移数, [起始位置])
,起始位置默认为0,即开头;1为当前位置;2为末尾。 - 只要打开文件就要注意编码问题!