欢迎光临散文网 会员登陆 & 注册

《无寿限音序器》汉化经历

2023-04-30 11:22 作者:Leua  | 我要投稿

因为总是要更改歌词字幕。我们决定更新制作流程,取代原本繁琐的手工工作。以下内容均获得了GPT的帮助。


import random
import re


# 定义处理字幕行的函数
def process_subtitle_line(subtitle_line):
   # 定义时间戳的正则表达式
   pattern = r"(\d{2}:\d{2}:\d{2},\d{3})"
   # 使用正则表达式找到所有匹配项
   matches = re.findall(pattern, subtitle_line)

   if matches:
       # 提取开始时间
       start_time = matches[0]
       # 将开始时间分解为小时、分钟、秒和毫秒
       hours, minutes, seconds, milliseconds = map(int, re.split(r"[:,]", start_time))

       # 将时间转换为总秒数
       total_seconds = hours * 3600 + minutes * 60 + seconds + milliseconds / 1000
       # 计算游戏时间戳
       game_timestamp = total_seconds * 100000

       # 生成随机数
       random_number = random.randint(-50, 49)
       # 更新游戏时间戳
       game_timestamp += random_number

       return int(game_timestamp)
   else:
       return None


# 定义文件路径
file_path = r'F:\aft\mdata\Me99\rom\mdata_pv_db.txt'
pv_id = 417
lyric_id_list = []
num = 0
# 读取文件
with open(file_path, 'r', encoding='utf-8') as file:
   lines = file.readlines()

# 遍历文件中的每一行
for line in lines:
   if f'pv_{pv_id}.lyric.' in line:
       # 分割行以提取歌词ID
       lyric_parts = line.split('=')
       lyric_key = lyric_parts[0].strip()
       lyric_id = int(lyric_key.split('.')[2])
       if lyric_id >= 100:
           lyric_id_list.append(lyric_id)

# 根据歌词ID排序歌词列表
lyric_id_list = sorted(lyric_id_list, key=lambda x: (x % 100))
print(lyric_id_list)

# 定义字幕文件名
filename = "exam.srt"
# 读取字幕文件
with open(filename, "r", encoding="utf-8") as file:
   lines = file.readlines()

# 遍历字幕文件的每一行
for line in lines:
   # 调用process_subtitle_line函数处理行
   timestamp = process_subtitle_line(line.strip())

   if timestamp:
       # 输出游戏时间戳和歌词ID
       print(f"TIME({timestamp});")
       print(f"LYRIC({lyric_id_list[num]}, -1);")
       num += 1


我将详细解释上述代码的功能和各个部分,特别关注细节。这段代码主要处理视频字幕(SRT格式)和歌词数据,将其转换为特定的格式。下面是对每行代码的详细解释。

没错,你可以看见这些代码居然具有一些神秘的样式,这只是直接从gpt网页粘贴过来就有了的。我已经试过了,让上面那一段也加上,但是我失败了。

首先,导入所需的模块:


pythonCopy code

import random

import re

random库用于生成随机数,re库用于处理正则表达式。

接下来,定义一个名为process_subtitle_line的函数,用于处理单个字幕行。这个函数的主要目的是提取字幕的开始时间并将其转换为游戏时间戳。此外,它还会为游戏时间戳添加一个随机数,以实现微小的偏移。


pythonCopy code

def process_subtitle_line(subtitle_line):

subtitle_line表示输入的一行字幕。


pythonCopy code

pattern = r"(\d{2}:\d{2}:\d{2},\d{3})"

这里定义了一个名为pattern(样式(嘻嘻,我是宋体哦!是宋体吧应该……))的正则表达式,用于匹配字幕中的时间格式(小时:分钟:秒,毫秒)。正则表达式的解释如下:

  • \d: 匹配一个数字字符。

  • {2}: 表示前面的规则应重复2次,即匹配两个连续的数字字符。

  • :: 匹配冒号字符。

  • ,: 匹配逗号字符。

  • {3}: 表示前面的规则应重复3次,即匹配三个连续的数字字符。

  • (): 捕获括号内的匹配项。

所以,这个正则表达式匹配的字符串格式为:两个数字、冒号、两个数字、冒号、两个数字、逗号、三个数字。这正是字幕文件中时间戳的格式。


pythonCopy code

matches = re.findall(pattern, subtitle_line)

使用re.findall()函数,在subtitle_line中查找与pattern匹配的所有时间。将结果存储在matches列表中。


pythonCopy code

if matches:        start_time = matches[0]

如果matches列表不为空,则取出第一个匹配项,即字幕的开始时间。这里假设每个字幕行只有一个时间戳。


pythonCopy code

  hours, minutes, seconds, milliseconds = map(int, re.split(r"[:,]", start_time))

start_time字符串分割成小时、分钟、秒和毫秒四个部分。使用re.split()函数根据冒号和逗号进行分割。将得到的字符串列表转换为整数列表,然后分别赋值给变量hoursminutessecondsmilliseconds


pythonCopy code

  total_seconds = hours * 3600 + minutes * 60 + seconds + milliseconds / 1000

计算总秒数。将小时、分钟、秒和毫秒分别转换为秒并求和。小时乘以3600(每小时3600秒),分钟乘以60(每分钟60秒),毫秒除以1000(每秒1000毫秒)。


pythonCopy code

  game_timestamp = total_seconds * 100000


将总秒数乘以100000,以获取游戏时间戳。这里的100000是一个换算系数,将时间转换为游戏中的单位。


pythonCopy code

  random_number = random.randint(-50, 49)


生成一个介于-50和49之间(包括-50和49)的随机整数。这个随机数将用于稍后对游戏时间戳进行微调。


pythonCopy code

  game_timestamp += random_number


将随机数添加到游戏时间戳,使时间戳稍微偏移。这有助于确保游戏中的事件不会完全按照原始时间戳进行。


pythonCopy code

  return int(game_timestamp)


将游戏时间戳转换为整数并返回。


pythonCopy code

else:        return None


如果没有找到匹配的时间戳,则返回None。


pythonCopy code

file_path = r'F:\aft\mdata\Me99\rom\mdata_pv_db.txt'


定义一个变量file_path,表示存储歌词数据的文件路径。

在字符串前面加上r,表示这是一个原始字符串(raw string)。原始字符串不会对反斜杠(\)进行转义处理。这在表示文件路径时非常有用,因为路径中通常包含反斜杠,而在普通字符串中,反斜杠表示转义字符。

例如,如果不使用原始字符串,我们需要使用双反斜杠(\)表示一个反斜杠,如下所示:


pythonCopy code

file_path = 'F:\\aft\\mdata\\Me99\\rom\\mdata_pv_db.txt'


为了避免这种冗余,我们使用原始字符串,只需在路径中使用单个反斜杠即可。这使得表示文件路径更加简洁和清晰。


pythonCopy code

pv_id = 417


定义一个整数变量pv_id,用于从文件中提取特定的歌曲ID。


pythonCopy code

lyric_id_list = []


定义一个名为lyric_id_list的空列表,用于存储提取到的歌词ID。


pythonCopy code

num = 0


定义一个整数变量num,初始化为0。这个变量将用于记录已处理的字幕行数。


pythonCopy code

with open(file_path, 'r', encoding='utf-8') as file:    lines = file.readlines()


使用with语句和open()函数打开file_path指定的文件,以只读模式('r')和指定的编码格式('utf-8')。使用readlines()函数读取文件的所有行,并将它们存储在变量lines中。


pythonCopy code

for line in lines:    if f'pv_{pv_id}.lyric.' in line:        lyric_parts = line.split('=')


遍历文件中的每一行。如果当前行包含指定的歌词ID(pv_{pv_id}.lyric.),则使用split()函数根据等号('=')将当前行分割成两部分,并将它们存储在变量lyric_parts中。


pythonCopy code

  lyric_key = lyric_parts[0].strip()


lyric_parts列表的第一个元素(歌词ID部分),使用strip()函数去除首尾空白字符,并将结果存储在变量lyric_key中。


pythonCopy code

  lyric_id = int(lyric_key.split('.')[2])


使用split()函数根据句点('.')将lyric_key分割成多个部分,然后取第三个部分(索引为2),将其转换为整数并赋值给lyric_id


pythonCopy code

  if lyric_id >= 100:            lyric_id_list.append(lyric_id)


如果lyric_id大于等于100,将其添加到lyric_id_list列表中。这个条件用于筛选有效的歌词ID。


pythonCopy code

lyric_id_list = sorted(lyric_id_list, key=lambda x: (x % 100))


lyric_id_list列表进行排序。使用sorted()函数和自定义排序键(key=lambda x: (x % 100)),按歌词ID除以100的余数进行排序。这样可以确保列表中的歌词ID按照特定顺序排列。


pythonCopy code

print(lyric_id_list)


打印排序后的lyric_id_list列表。


pythonCopy code

filename = "exam.srt"


定义一个变量filename,表示字幕文件(SRT格式)的名称。


pythonCopy code

with open(filename, "r", encoding="utf-8") as file:    lines = file.readlines()


使用with语句和open()函数打开filename指定的文件,以只读模式('r')和指定的编码格式('utf-8')。使用readlines()函数读取文件的所有行,并将它们存储在变量lines中。


pythonCopy code

for line in lines:    timestamp = process_subtitle_line(line.strip())


遍历字幕文件中的每一行。使用strip()函数去除首尾空白字符,然后将当前行作为参数传递给process_subtitle_line()函数。将返回的游戏时间戳存储在变量timestamp中。


pythonCopy code

if timestamp:        print(f"TIME({timestamp});")


如果timestamp不为None(即当前行包含有效的时间戳),则打印游戏时间戳。


pythonCopy code

  print(f"LYRIC({lyric_id_list[num]}, -1);")


打印当前歌词ID(从lyric_id_list列表中取出,索引为num)和固定值-1。这行输出表示在timestamp指定的时间播放歌词。


pythonCopy code

  num += 1


将变量num的值加1,表示已处理的字幕行数加1。

至此,所有代码已经详细解释完毕。这段代码从歌词数据文件和字幕文件中提取信息,然后生成游戏时间戳和对应的歌词ID,以便在游戏中使用。(你怎么知道要在游戏里用的?)

可以看到它现在就是可以自动产生需要的剧本文件的格式。我们将这些文本保存的一个新的剧本文件,然后选择它和原本的剧本文件两个一起拖入到专用的编辑器,就可以按照顺序自动合并。相当于把这些新的字幕指令插入了原本的文件。

不变的是,我们仍然需要手工选择新的时间点,这些地方就是原本的字幕被拆分的时间,并且设置新的字幕的id。这些过程是必要的。但是现在那个srt字幕文件里的分秒顺序的时间可以直接转换为十万倍的秒,为了还原游戏十万倍秒里的情况,srt不支持的最后两位数字因为srt最细到秒的一千倍,相比十万少了两个零,所以直接换算的话最后两位就直接是0,现在它们也可以随机生成了,尽管这会导致微乎其微的偏差,但小于秒的千分之一,这谁看得出来?

并且现在是有了自动的新歌词字幕的指令,里面的字幕id也是自动匹配的。相当于我们减少了一些复杂和重复的数据的处理,比如时间换算,id的引用。


屏幕截图录像编辑-FastStoneCapture 9.9 单文件版
https://www.52pojie.cn/thread-1729686-1-1.html
(出处: 吾爱破解论坛)
绝绝子!我终于找到了我一直想要的pc也能滚动截屏的软件!

我能说……当它揣测到我的真实意图的时候,我感到好像被尖端从背后刺入窥探内心,有点害怕了。尽管GPT4在一些运算上还是会出错,但是如果我们加上自己的努力后的判断,就能认识到错误的地方并且学习到新闻!

《无寿限音序器》汉化经历的评论 (共 条)

分享到微博请遵守国家法律