《無壽限音序器》漢化經(jīng)歷
因?yàn)榭偸且母柙~字幕。我們決定更新制作流程,取代原本繁瑣的手工工作。以下內(nèi)容均獲得了GPT的幫助。
import random
import re
# 定義處理字幕行的函數(shù)
def process_subtitle_line(subtitle_line):
? ?# 定義時(shí)間戳的正則表達(dá)式
? ?pattern = r"(\d{2}:\d{2}:\d{2},\d{3})"
? ?# 使用正則表達(dá)式找到所有匹配項(xiàng)
? ?matches = re.findall(pattern, subtitle_line)
? ?if matches:
? ? ? ?# 提取開始時(shí)間
? ? ? ?start_time = matches[0]
? ? ? ?# 將開始時(shí)間分解為小時(shí)、分鐘、秒和毫秒
? ? ? ?hours, minutes, seconds, milliseconds = map(int, re.split(r"[:,]", start_time))
? ? ? ?# 將時(shí)間轉(zhuǎn)換為總秒數(shù)
? ? ? ?total_seconds = hours * 3600 + minutes * 60 + seconds + milliseconds / 1000
? ? ? ?# 計(jì)算游戲時(shí)間戳
? ? ? ?game_timestamp = total_seconds * 100000
? ? ? ?# 生成隨機(jī)數(shù)
? ? ? ?random_number = random.randint(-50, 49)
? ? ? ?# 更新游戲時(shí)間戳
? ? ? ?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)
# 根據(jù)歌詞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:
? ?# 調(diào)用process_subtitle_line函數(shù)處理行
? ?timestamp = process_subtitle_line(line.strip())
? ?if timestamp:
? ? ? ?# 輸出游戲時(shí)間戳和歌詞ID
? ? ? ?print(f"TIME({timestamp});")
? ? ? ?print(f"LYRIC({lyric_id_list[num]}, -1);")
? ? ? ?num += 1
我將詳細(xì)解釋上述代碼的功能和各個(gè)部分,特別關(guān)注細(xì)節(jié)。這段代碼主要處理視頻字幕(SRT格式)和歌詞數(shù)據(jù),將其轉(zhuǎn)換為特定的格式。下面是對(duì)每行代碼的詳細(xì)解釋。
沒錯(cuò),你可以看見這些代碼居然具有一些神秘的樣式,這只是直接從gpt網(wǎng)頁粘貼過來就有了的。我已經(jīng)試過了,讓上面那一段也加上,但是我失敗了。
首先,導(dǎo)入所需的模塊:
pythonCopy code
import random
import re
random
庫用于生成隨機(jī)數(shù),re
庫用于處理正則表達(dá)式。
接下來,定義一個(gè)名為process_subtitle_line
的函數(shù),用于處理單個(gè)字幕行。這個(gè)函數(shù)的主要目的是提取字幕的開始時(shí)間并將其轉(zhuǎn)換為游戲時(shí)間戳。此外,它還會(huì)為游戲時(shí)間戳添加一個(gè)隨機(jī)數(shù),以實(shí)現(xiàn)微小的偏移。
pythonCopy code
def process_subtitle_line(subtitle_line):
subtitle_line
表示輸入的一行字幕。
pythonCopy code
pattern = r"(\d{2}:\d{2}:\d{2},\d{3})"
這里定義了一個(gè)名為pattern(樣式(嘻嘻,我是宋體哦!是宋體吧應(yīng)該……))
的正則表達(dá)式,用于匹配字幕中的時(shí)間格式(小時(shí):分鐘:秒,毫秒)。正則表達(dá)式的解釋如下:
\d
: 匹配一個(gè)數(shù)字字符。{2}
: 表示前面的規(guī)則應(yīng)重復(fù)2次,即匹配兩個(gè)連續(xù)的數(shù)字字符。:
: 匹配冒號(hào)字符。,
: 匹配逗號(hào)字符。{3}
: 表示前面的規(guī)則應(yīng)重復(fù)3次,即匹配三個(gè)連續(xù)的數(shù)字字符。()
: 捕獲括號(hào)內(nèi)的匹配項(xiàng)。
所以,這個(gè)正則表達(dá)式匹配的字符串格式為:兩個(gè)數(shù)字、冒號(hào)、兩個(gè)數(shù)字、冒號(hào)、兩個(gè)數(shù)字、逗號(hào)、三個(gè)數(shù)字。這正是字幕文件中時(shí)間戳的格式。
pythonCopy code
matches = re.findall(pattern, subtitle_line)
使用re.findall()
函數(shù),在subtitle_line
中查找與pattern
匹配的所有時(shí)間。將結(jié)果存儲(chǔ)在matches
列表中。
pythonCopy code
if matches: ? ? ? ?start_time = matches[0]
如果matches
列表不為空,則取出第一個(gè)匹配項(xiàng),即字幕的開始時(shí)間。這里假設(shè)每個(gè)字幕行只有一個(gè)時(shí)間戳。
pythonCopy code
? hours, minutes, seconds, milliseconds = map(int, re.split(r"[:,]", start_time))
將start_time
字符串分割成小時(shí)、分鐘、秒和毫秒四個(gè)部分。使用re.split()
函數(shù)根據(jù)冒號(hào)和逗號(hào)進(jìn)行分割。將得到的字符串列表轉(zhuǎn)換為整數(shù)列表,然后分別賦值給變量hours
、minutes
、seconds
和milliseconds
。
pythonCopy code
? total_seconds = hours * 3600 + minutes * 60 + seconds + milliseconds / 1000
計(jì)算總秒數(shù)。將小時(shí)、分鐘、秒和毫秒分別轉(zhuǎn)換為秒并求和。小時(shí)乘以3600(每小時(shí)3600秒),分鐘乘以60(每分鐘60秒),毫秒除以1000(每秒1000毫秒)。
pythonCopy code
? game_timestamp = total_seconds * 100000
將總秒數(shù)乘以100000,以獲取游戲時(shí)間戳。這里的100000是一個(gè)換算系數(shù),將時(shí)間轉(zhuǎn)換為游戲中的單位。
pythonCopy code
? random_number = random.randint(-50, 49)
生成一個(gè)介于-50和49之間(包括-50和49)的隨機(jī)整數(shù)。這個(gè)隨機(jī)數(shù)將用于稍后對(duì)游戲時(shí)間戳進(jìn)行微調(diào)。
pythonCopy code
? game_timestamp += random_number
將隨機(jī)數(shù)添加到游戲時(shí)間戳,使時(shí)間戳稍微偏移。這有助于確保游戲中的事件不會(huì)完全按照原始時(shí)間戳進(jìn)行。
pythonCopy code
? return int(game_timestamp)
將游戲時(shí)間戳轉(zhuǎn)換為整數(shù)并返回。
pythonCopy code
else: ? ? ? ?return None
如果沒有找到匹配的時(shí)間戳,則返回None。
pythonCopy code
file_path = r'F:\aft\mdata\Me99\rom\mdata_pv_db.txt'
定義一個(gè)變量file_path
,表示存儲(chǔ)歌詞數(shù)據(jù)的文件路徑。
在字符串前面加上r
,表示這是一個(gè)原始字符串(raw string)。原始字符串不會(huì)對(duì)反斜杠(\)進(jìn)行轉(zhuǎn)義處理。這在表示文件路徑時(shí)非常有用,因?yàn)槁窂街型ǔ0葱备?,而在普通字符串中,反斜杠表示轉(zhuǎn)義字符。
例如,如果不使用原始字符串,我們需要使用雙反斜杠(\)表示一個(gè)反斜杠,如下所示:
pythonCopy code
file_path = 'F:\\aft\\mdata\\Me99\\rom\\mdata_pv_db.txt'
為了避免這種冗余,我們使用原始字符串,只需在路徑中使用單個(gè)反斜杠即可。這使得表示文件路徑更加簡(jiǎn)潔和清晰。
pythonCopy code
pv_id = 417
定義一個(gè)整數(shù)變量pv_id
,用于從文件中提取特定的歌曲ID。
pythonCopy code
lyric_id_list = []
定義一個(gè)名為lyric_id_list
的空列表,用于存儲(chǔ)提取到的歌詞ID。
pythonCopy code
num = 0
定義一個(gè)整數(shù)變量num
,初始化為0。這個(gè)變量將用于記錄已處理的字幕行數(shù)。
pythonCopy code
with open(file_path, 'r', encoding='utf-8') as file: ? ?lines = file.readlines()
使用with
語句和open()
函數(shù)打開file_path
指定的文件,以只讀模式('r')和指定的編碼格式('utf-8')。使用readlines()
函數(shù)讀取文件的所有行,并將它們存儲(chǔ)在變量lines
中。
pythonCopy code
for line in lines: ? ?if f'pv_{pv_id}.lyric.' in line: ? ? ? ?lyric_parts = line.split('=')
遍歷文件中的每一行。如果當(dāng)前行包含指定的歌詞ID(pv_{pv_id}.lyric.
),則使用split()
函數(shù)根據(jù)等號(hào)('=')將當(dāng)前行分割成兩部分,并將它們存儲(chǔ)在變量lyric_parts
中。
pythonCopy code
? lyric_key = lyric_parts[0].strip()
取lyric_parts
列表的第一個(gè)元素(歌詞ID部分),使用strip()
函數(shù)去除首尾空白字符,并將結(jié)果存儲(chǔ)在變量lyric_key
中。
pythonCopy code
? lyric_id = int(lyric_key.split('.')[2])
使用split()
函數(shù)根據(jù)句點(diǎn)('.')將lyric_key
分割成多個(gè)部分,然后取第三個(gè)部分(索引為2),將其轉(zhuǎn)換為整數(shù)并賦值給lyric_id
。
pythonCopy code
? if lyric_id >= 100: ? ? ? ? ? ?lyric_id_list.append(lyric_id)
如果lyric_id
大于等于100,將其添加到lyric_id_list
列表中。這個(gè)條件用于篩選有效的歌詞ID。
pythonCopy code
lyric_id_list = sorted(lyric_id_list, key=lambda x: (x % 100))
對(duì)lyric_id_list
列表進(jìn)行排序。使用sorted()
函數(shù)和自定義排序鍵(key=lambda x: (x % 100)
),按歌詞ID除以100的余數(shù)進(jìn)行排序。這樣可以確保列表中的歌詞ID按照特定順序排列。
pythonCopy code
print(lyric_id_list)
打印排序后的lyric_id_list
列表。
pythonCopy code
filename = "exam.srt"
定義一個(gè)變量filename
,表示字幕文件(SRT格式)的名稱。
pythonCopy code
with open(filename, "r", encoding="utf-8") as file: ? ?lines = file.readlines()
使用with
語句和open()
函數(shù)打開filename
指定的文件,以只讀模式('r')和指定的編碼格式('utf-8')。使用readlines()
函數(shù)讀取文件的所有行,并將它們存儲(chǔ)在變量lines
中。
pythonCopy code
for line in lines: ? ?timestamp = process_subtitle_line(line.strip())
遍歷字幕文件中的每一行。使用strip()
函數(shù)去除首尾空白字符,然后將當(dāng)前行作為參數(shù)傳遞給process_subtitle_line()
函數(shù)。將返回的游戲時(shí)間戳存儲(chǔ)在變量timestamp
中。
pythonCopy code
if timestamp: ? ? ? ?print(f"TIME({timestamp});")
如果timestamp
不為None(即當(dāng)前行包含有效的時(shí)間戳),則打印游戲時(shí)間戳。
pythonCopy code
? print(f"LYRIC({lyric_id_list[num]}, -1);")
打印當(dāng)前歌詞ID(從lyric_id_list
列表中取出,索引為num
)和固定值-1。這行輸出表示在timestamp
指定的時(shí)間播放歌詞。
pythonCopy code
? num += 1
將變量num
的值加1,表示已處理的字幕行數(shù)加1。
至此,所有代碼已經(jīng)詳細(xì)解釋完畢。這段代碼從歌詞數(shù)據(jù)文件和字幕文件中提取信息,然后生成游戲時(shí)間戳和對(duì)應(yīng)的歌詞ID,以便在游戲中使用。(你怎么知道要在游戲里用的?)

可以看到它現(xiàn)在就是可以自動(dòng)產(chǎn)生需要的劇本文件的格式。我們將這些文本保存的一個(gè)新的劇本文件,然后選擇它和原本的劇本文件兩個(gè)一起拖入到專用的編輯器,就可以按照順序自動(dòng)合并。相當(dāng)于把這些新的字幕指令插入了原本的文件。
不變的是,我們?nèi)匀恍枰止みx擇新的時(shí)間點(diǎn),這些地方就是原本的字幕被拆分的時(shí)間,并且設(shè)置新的字幕的id。這些過程是必要的。但是現(xiàn)在那個(gè)srt字幕文件里的分秒順序的時(shí)間可以直接轉(zhuǎn)換為十萬倍的秒,為了還原游戲十萬倍秒里的情況,srt不支持的最后兩位數(shù)字因?yàn)閟rt最細(xì)到秒的一千倍,相比十萬少了兩個(gè)零,所以直接換算的話最后兩位就直接是0,現(xiàn)在它們也可以隨機(jī)生成了,盡管這會(huì)導(dǎo)致微乎其微的偏差,但小于秒的千分之一,這誰看得出來?
并且現(xiàn)在是有了自動(dòng)的新歌詞字幕的指令,里面的字幕id也是自動(dòng)匹配的。相當(dāng)于我們減少了一些復(fù)雜和重復(fù)的數(shù)據(jù)的處理,比如時(shí)間換算,id的引用。

https://www.52pojie.cn/thread-1729686-1-1.html
(出處: 吾愛破解論壇)
絕絕子!我終于找到了我一直想要的pc也能滾動(dòng)截屏的軟件!
我能說……當(dāng)它揣測(cè)到我的真實(shí)意圖的時(shí)候,我感到好像被尖端從背后刺入窺探內(nèi)心,有點(diǎn)害怕了。盡管GPT4在一些運(yùn)算上還是會(huì)出錯(cuò),但是如果我們加上自己的努力后的判斷,就能認(rèn)識(shí)到錯(cuò)誤的地方并且學(xué)習(xí)到新聞!