本帖最后由 wzvideni 于 2023-11-20 14:15 编辑
双语歌曲LRC歌词文件整理
2023:11:20更新:
- 修改删除[offset:0]的判断,添加被之前删除[offset:0],加入判断如果在时间轴[00:00]前不存在offset标签自动添加[offset:0]
- 添加翻译时间轴的矫正,毫秒差在10ms内的判断为同一时间轴
强迫症犯了,自己写的一个双语歌词歌曲LRC歌词文件的自动整理程序,会递归整理输入目录下的所有LRC文件,代码如下:
import os
import re
# 无用内容元组
useless = ('', '\\\\', '//')
def lyrics_editor(lrc_path):
# 新建一个空的歌词字典,键为时间轴或者歌曲信息,值为值为歌词列表(列表是为了存歌词翻译)
lrc_map = {}
with (open(lrc_path, encoding='utf-8') as lrc):
# 如果有歌词和翻译时间轴不对应的情况,在修正后,将不对应的键添加进del_timeline列表统一删除
del_timeline = list()
# 逐行读取:“[00:00.00]这里是歌词”
for line in lrc:
# 判断读取行是否为空白字符(换行符),过滤空白行
if not line.isspace():
# 匹配时间轴:“[00:00.00]”
timeline = re.search(r'\[.*]', line).group()
# 将读取行中的时间轴和歌词末尾的换行符清除后则为歌词
lyrics = line.replace(timeline, '').strip()
# 如果时间轴中包含“by”、”offset“、”kana“其中的一个并且起始索引都为1,此标签大部分为垃圾信息,跳过循环
if timeline.find('by') == 1 or timeline.find('kana') == 1:
continue
# 如果歌词内容在无用内容元组中或者包含“QQ音乐”、跳过循环
if lyrics in useless or lyrics.find('QQ音乐') != -1:
# 如果不是时间轴中包含“ti”、”ar“、”al“其中的一个并且起始索引都为1则表示读取的是歌曲的相关信息,则跳过循环
if not (timeline.find('ti') == 1 or timeline.find('offset') == 1 or timeline.find(
'ar') == 1 or timeline.find('al') == 1):
continue
# 时间轴不存在歌词字典中则表示现在为写入原歌词阶段
if timeline not in lrc_map:
# 将时间轴为键,歌词为值存入歌词字典,其中歌词以列表的形式存储
lrc_map[timeline] = list()
lrc_map[timeline].append(lyrics)
# 以下部分是校正时间轴的代码
# 分割时间轴对应的分
timeline_minutes = timeline[1:3]
# 分割时间轴对应的秒
timeline_seconds = timeline[4:6]
# 分割时间轴对应的毫秒
timeline_millisecond = timeline[7:9]
# 如果分割时间轴对应的分是数字就表示是时间轴
if timeline_minutes.isdigit():
# 遍历歌词字典查找是否有歌词和键不匹配的情况
for key, value in lrc_map.items():
# 分割键对应的分
minutes = key[1:3]
# 分割键对应的秒
seconds = key[4:6]
# 分割键对应的毫秒
millisecond = key[7:9]
# 继续判断是否是数字
if minutes.isdigit():
# 分秒一定要相同
if timeline_minutes == minutes and timeline_seconds == seconds:
# 判断毫秒差绝对值不超过10ms,则表示翻译时间轴不对应并找到了正确的时间轴
if abs(int(timeline_millisecond) - int(millisecond)) < 10:
# 如果当前歌词不存在于歌词字典才继续,防止重复添加
if lyrics not in lrc_map[key]:
# 把时间轴添加进入将要删除的时间轴列表
del_timeline.append(timeline)
# 往正确的时间轴写入翻译
lrc_map[key].append(lyrics)
# 否则时间轴存在歌词字典中则表示现在为写入歌词翻译阶段
else:
# 如果歌词翻译不在键对应的歌词列表中则添加进去,防止重复添加
if lyrics not in lrc_map[timeline]:
# 将歌词添加到键对应的值列表中
lrc_map[timeline].append(lyrics)
for del_key in del_timeline:
del lrc_map[del_key]
# 清空原文件歌词内容
with open(lrc_path, 'w') as lrc:
lrc.truncate(0)
offset_flag = 1
last_key = ''
# 遍历歌词字典
for key, value in lrc_map.items():
# 在00:00.00前写入换行符,分隔歌曲信息和歌词
if offset_flag == 1:
if key.find('00:00') == 1:
# 查找00:00.00是否存在offset,不存在则自动添加
if last_key.find('offset') == 1:
with open(lrc_path, 'a', encoding='utf-8') as lrc:
lrc.write('\n')
else:
with open(lrc_path, 'a', encoding='utf-8') as lrc:
lrc.write('[offset:0]\n\n')
offset_flag = 0
# 当前歌词值列表长度大于1(即存在翻译时)就额外在歌词和翻译前添加一个换行符
# 写入前换行便于和歌曲信息隔开来(但是仅限于翻译存在时可以很好地分隔开来)
if len(value) > 1:
with open(lrc_path, 'a', encoding='utf-8') as lrc:
lrc.write('\n')
# 遍历当前时间轴键的歌词列表把时间轴和歌词拼接后写入歌词文件
for lyrics in value:
with open(lrc_path, 'a', encoding='utf-8') as lrc:
lrc.write(f'{key}{lyrics}\n')
last_key = key
def walk_path(input_path):
# 统计更改的文件数量
count = 0
# 遍历目录
for root, dirs, files in os.walk(input_path):
# 循环目录中的文件
for file in files:
# 匹配*.lrc文件
match = re.search(r'.*\.lrc$', os.path.join(root, file))
# 匹配成功
if match:
# 获取路径
lrc_path = match.group()
# 执行编辑
lyrics_editor(lrc_path)
# 输出编辑完成的文件路径
print(lrc_path)
count += 1
print(f'\n已处理数量:{count}')
if __name__ == '__main__':
print('双语歌曲LRC歌词文件整理')
# lrc文件所在目录
path = input("请输入lrc文件所在目录的路径:")
while path == '':
path = input('路径不能为空:')
walk_path(path)
input('按任意键继续……')
整理前:
[ti:シュガーコート]
[ar:Dazbee (ダズビー)]
[al:シュガーコート]
[by:]
[offset:0]
[kana:1し1ささ1がわ1ま1お1きょく1ささ1がわ1ま1お2はだし1に1だ1ふ1お1いき1す1ほそ1て1あし1だる1じょう1しき1わす1とめ1がね1はず1じゅ1もん1さけ1い1くび1つめ1た1と1あい1ふう1せん1しぼ1ま1ちが1いのち1か1か1あい1ほ1かぜ1ほお1さ1ゆ1ぜん1ぶ1しっ1た1たか1な1むね1のう1こ1は1や1やまい1げ1こう1じ1こく1な1とき1あま1きら1くち1ぐせ1い1きず1うず1うず1くる1ほ1えい1えん1そら1しず1めい1てい1かん1いと1うば1ゆめ1み1いま1い1ふ1くび1つめ1た1と1し1げき1ほ1せん1こう1き1そだ1かさ1いき1ひと1じ1ごく1きみ]
[00:00.00]シュガーコート - Dazbee (ダズビー)
[00:00.74]词:笹川真生
[00:01.17]曲:笹川真生
[00:01.70]裸足のままどっか逃げ出したい?
[00:05.29]まだ腑に落ちたい?
[00:07.10]それでどうしたい?
[00:09.14]息ひとつさえうまく吸えないで
[00:12.58]その細い手足では怠いでしょう
...
[ti:シュガーコート]
[ar:Dazbee (ダズビー)]
[al:シュガーコート]
[by:]
[offset:0]
[kana:1し1ささ1がわ1ま1お1きょく1ささ1がわ1ま1お2はだし1に1だ1ふ1お1いき1す1ほそ1て1あし1だる1じょう1しき1わす1とめ1がね1はず1じゅ1もん1さけ1い1くび1つめ1た1と1あい1ふう1せん1しぼ1ま1ちが1いのち1か1か1あい1ほ1かぜ1ほお1さ1ゆ1ぜん1ぶ1しっ1た1たか1な1むね1のう1こ1は1や1やまい1げ1こう1じ1こく1な1とき1あま1きら1くち1ぐせ1い1きず1うず1うず1くる1ほ1えい1えん1そら1しず1めい1てい1かん1いと1うば1ゆめ1み1いま1い1ふ1くび1つめ1た1と1し1げき1ほ1せん1こう1き1そだ1かさ1いき1ひと1じ1ごく1きみ]
[00:00.00]QQ音乐享有本翻译作品的著作权
[00:00.74]//
[00:01.17]//
[00:01.70]想赤脚逃到某个地方吗
[00:05.29]想要了解更多吗
[00:07.10]然后呢 你想怎么做呢
[00:09.14]明明连正常呼吸都如此困难了
[00:12.58]你那纤细的四肢根本难以抵御吧
...
整理后:
[ti:シュガーコート]
[ar:Dazbee (ダズビー)]
[al:シュガーコート]
[00:00.00]シュガーコート - Dazbee (ダズビー)
[00:00.74]词:笹川真生
[00:01.17]曲:笹川真生
[00:01.70]裸足のままどっか逃げ出したい?
[00:01.70]想赤脚逃到某个地方吗
[00:05.29]まだ腑に落ちたい?
[00:05.29]想要了解更多吗
[00:07.10]それでどうしたい?
[00:07.10]然后呢 你想怎么做呢
[00:09.14]息ひとつさえうまく吸えないで
[00:09.14]明明连正常呼吸都如此困难了
[00:12.58]その細い手足では怠いでしょう
[00:12.58]你那纤细的四肢根本难以抵御吧
运行截图:
运行截图
exe编译程序:
https://wwur.lanzout.com/iFHR71fe52yh |