利用Python將WEBVTT格式的視訊字幕檔案轉為SRT格式
1 WebVTT & SRT 格式
WebVTT字幕格式與SRT字幕格式主要區別在於時間格式的區分。
下面是一個WebVTT格式的字幕檔案
WEBVTT
1
00:00:20.000 --> 00:00:24.400
En réponse à l'augmentation dramatique
de la criminalité dans certains quartiers,
2
00:00:24.600 --> 00:00:27.800
Le gouvernement se félicite pour les prochaines élections…
對應的SRT字幕格式則為
1
00:00:20,000 --> 00:00:24,400
En réponse à l'augmentation dramatique
de la criminalité dans certains quartiers,
2
00:00:24,600 --> 00:00:27,800
Le gouvernement se félicite pour les prochaines élections…
可以看到兩種格式的檔案主要有兩個的區別:
WebVTT格式的檔案頭有
WEBVTT
標識,而SRT格式的檔案則沒有;WebVTT格式的時間為
00:00:20.000 --> 00:00:24.400
,而SRT格式的時間為00:00:20,000 --> 00:00:24,400
;即一個為.
一個為,
。
有個上述的基本認識之後,要將WebVTT格式的字幕檔案轉為SRT格式的字幕檔案就迎刃而解了。
2 解決方案
為了實現WebVTT轉換為SRT檔案格式,本解決方案採用Python實現,使用PyQt4提供介面。在介面設計中,使用到了Qt Designer進行介面設計。
程式介面如下圖所示:
2.1 QT Designer 介面設計
利用QT Designer設計完介面後,將檔案儲存為.ui
字尾的檔名。然後利用pyuic.py
將'.ui
檔案轉為.py
檔案。命令如下:
C:\>python "D:\Program Files (x86)\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" -o vtt2srt_ui.py vtt2srt.ui
這裡介面檔案文vtt2srt.ui
,生成後的python檔案為vtt2srt_ui.py
。
備註:pyuic.py
在安裝完PyQt時就預設安裝上了,路徑應該為XXX\Lib\site-packages\PyQt4\uic
,其中XXX
為Python路徑。 如果你找不到,可以使用Everything進行搜尋。
2.2 引用介面檔案
在建立好UI檔案並將其轉換為Python原始檔之後,就需要在我們的Python原始檔中使用該UI介面,PyQt Designer上已經有了詳細的說明,此外,由於個人英文水平有限,即便在這個胡謅兩句,各位看官也不一定能明白,畢竟存在資訊損耗嘛!所以介意各位看官移步到PyQt Designer手冊自行琢磨。
以下程式碼展示瞭如何引用PyQt的UI檔案。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui
from vtt2srt_ui import Ui_vtt2srt
class VTT2SRT(QtGui.QMainWindow, Ui_vtt2srt):
def __init__(self, parent=None):
super(VTT2SRT, self).__init__(parent)
self.setupUi(self)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
vtt2srt = VTT2SRT()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
在上面的程式碼中我們只是引用了UI檔案,並將通過QT Designer設計的介面顯示出來,除此之外,沒有任何實質性的東西。接下來的工作就是響應各種訊息。
2.3 WebVTT 轉為 SRT
該程式建立兩個文字輸入框、兩個標籤以及三個按鈕,介面稍顯醜陋。接下來就是對按鈕的響應以執行相應的操作。程式碼如下:
class VTT2SRT(QtGui.QMainWindow, Ui_vtt2srt):
def __init__(self, parent=None):
super(VTT2SRT, self).__init__(parent)
self.setupUi(self)
self.show()
self.output_button.clicked.connect(lambda: self.open_file(1))
self.input_button.clicked.connect(lambda: self.open_file(0))
self.convert.clicked.connect(self.vtt2srt)
def open_file(self, flag):
fname = QtGui.QFileDialog.getOpenFileName(self, u'開啟檔案')
if flag == 1:
self.output_file.setText(fname)
else:
self.input_file.setText(fname)
def vtt2srt(self):
infile = self.input_file.text()
outfile = self.output_file.text()
# using thread is more reasonable
inf = open(infile, 'r')
outf = open(outfile, 'w')
line = inf.readline()
rep = re.compile('\.')
for line in inf:
if re.search('^WEBVTT', line):
continue
if re.search('^[0-9][0-9]:[0-9][0-9].+ -->', line):
line = rep.sub(',', line)
outf.write(line)
inf.close()
outf.close()
在上述程式碼中,其中兩個按鈕分別對應兩個文字輸入框用於指定輸入檔案和輸出檔案,它們執行的動作類似,因此將其關聯到一個函式上。而核心的轉換工作則由第三個按鈕關聯的vtt2srt函式執行。
備註:在此處為了簡便,直接在介面執行緒中執行轉換;但當轉換工作非常耗時時,這樣做回將介面執行緒卡死。一般的做法是新建一個工作執行緒用於執行轉換工作。
3 總結
在我準備做這個轉換器的時候,原以為十分簡單。雖然它確實不復雜,只是將.
替換為,
,但在實現過程中卻還是會遇到很多問題,真是紙上得來終覺淺,絕知此事要躬行
。這個小程式還有以下幾可以改進:
- 輸入檔案是否為WebVTT格式,這個為了省事而沒有做的;
- 轉換工作轉移到工作執行緒中,避免介面執行緒假死;
- 異常處理。
附件: 原始碼及文件