第一次遇到字幕不准是『种出个地球』的中文字幕。疫情期间拉爸妈一起看的,没中文不行。当时我用了个 Emacs 脚本,按汉字数和单词数排了一下字幕,放在了纪录片分享贴。不过这个字幕有时快有时慢。后来我意识到 mpv 可以同时放两个字幕,我只调中文的时间就行了。另外,『三亿年』自带的英文字幕也是不准的,只听声音的话,还是有很多词汇不认识菜。于是就写了这么个 Guile 脚本。
用法的话,第一个参数是 srt 字幕文件名,第二个是表示有多少条字幕,第三个表示快结束时,字幕快了多少秒。
我遇到的字幕不准的特征是,开始的时候准,到后面会越来越快,最后会快上几十秒。
代码:
#!/usr/bin/guile -s
!#
(define srtname (cadr (command-line)))
(define stripes (string->number (caddr (command-line))))
(define seconds (string->number (cadddr (command-line))))
(use-modules (ice-9 textual-ports) (srfi srfi-19))
(let* ((read-line (lambda (port)
(let ((content (get-string-all port)))
(if (eof-object? content) '()
(string-split content #\newline)))))
(contents (call-with-input-file srtname read-line #:guess-encoding #t)))
(letrec ((adjust (lambda (lst i)
(if (pair? lst)
(let* ((data (string-split (car lst) #\space))
(aux (lambda (str i)
(let* ((str (string-append/shared
"1970-01-01 " str))
(date (string->date
str "~Y-~m-~d ~H:~M:~S,~N"))
(time (date->time-utc date))
(d (make-time
time-duration 0
(truncate/
i (truncate/
stripes seconds))))
(str (date->string
(time-utc->date
(add-duration time d))
"~T,~N")))
(substring/shared
str 0 (- (string-length str) 6)))))
(times-line (and (pair? data) (pair? (cdr data))
(pair? (cddr data))
(equal? (cadr data) "-->"))))
`(,(if times-line
(string-append/shared (aux (car data) i) " --> "
(aux (caddr data) i))
(car lst))
,@(adjust (cdr lst) (if times-line (1+ i) i))))
'()))))
(map display (map (lambda (s) (string-append/shared s "\n"))
(adjust contents 0)))))
我遇到的字幕不准的特征是,开始的时候准,到后面会越来越快,最后会快上几十秒。