Skip to content

Instantly share code, notes, and snippets.

@crimx
Last active March 18, 2017 11:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crimx/26fb2460f61e88c9bf4da9143c6561f9 to your computer and use it in GitHub Desktop.
Save crimx/26fb2460f61e88c9bf4da9143c6561f9 to your computer and use it in GitHub Desktop.
应急使用,合并两个中英 srt 字幕为上中下英双语,使用字幕组的 ass 样式。两个字幕在不同的 layer 所以允许保留各自的时间,不需要人工调整。先 npm install subtitles-parser
const path = require('path')
const fs = require('fs')
const subParser = require('subtitles-parser')
/* eslint-disable no-tabs */
var args = process.argv.slice(2)
if (args.length < 2) {
error('Need Two Files')
} else {
let chs
let eng
if (/eng$/i.test(path.parse(args[0]).name)) {
eng = readSrt(args[0])
chs = readSrt(args[1])
} else if (/eng$/i.test(path.parse(args[1]).name)) {
chs = readSrt(args[0])
eng = readSrt(args[1])
}
if (typeof eng === 'undefined') {
let data = readSrt(args[0])
if (containChinese(data[0].text)) {
chs = data
eng = readSrt(args[1])
} else {
eng = data
chs = readSrt(args[1])
}
}
let result = [
'[Script Info]',
'Title:CRIMX',
'Original Script:CRIMX',
'Synch Point:1',
'ScriptType:v4.00+',
'Collisions:Normal',
'Timer:100.0000',
'',
'[V4+ Styles]',
'Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding',
'Style: Default,方正黑体简体,20,&H00FFFFFF,&HF0000000,&H00000000,&H32000000,0,0,0,0,100,100,0,0.00,1,2,1,2,5,5,6,134',
'',
'[Events]',
'Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text'
].join('\n')
result +=
// chs subs
chs.map(sub => {
var start = sub.startTime.replace(/,/g, '.').match(/\d:\d{2}:\d{2}.\d{2}/)[0]
var end = sub.endTime.replace(/,/g, '.').match(/\d:\d{2}:\d{2}.\d{2}/)[0]
return `Dialogue: 0,${start},${end},*Default,NTP,0000,0000,0000,,${sub.text.replace(/\n/g, ' ')}\\N{\\fn方正黑体简体}{\\fs10}{\\bord1}{\\shad1}{\\b0}{\\c&HFFFFFF&}{\\3c&H111111&}{\\4c&H111111&} \\N`
}).join('\n') +
'\n' +
// eng subs
eng.map(sub => {
var start = sub.startTime.replace(/,/g, '.').match(/\d:\d{2}:\d{2}.\d{2}/)[0]
var end = sub.endTime.replace(/,/g, '.').match(/\d:\d{2}:\d{2}.\d{2}/)[0]
return `Dialogue: 1,${start},${end},*Default,NTP,0000,0000,0000,, \\N{\\fn方正黑体简体}{\\fs10}{\\bord1}{\\shad1}{\\b0}{\\c&HFFFFFF&}{\\3c&H111111&}{\\4c&H111111&}${sub.text.replace(/\n/g, ' ')}`
}).join('\n')
let encode = 'utf8'
// windows uses utf16le with BOM
if (/^win/i.test(process.platform)) {
result = '\ufeff' + result.replace(/\n/g, '\r\n')
encode = 'utf16le'
}
fs.writeFileSync(`${path.parse(args[0]).name.replace(/[.-_](eng|chs)$/i, '.chs&eng')}.ass`, result, encode)
}
function readSrt (path) {
var buffer = fs.readFileSync(path)
var result = subParser.fromSrt(buffer.toString())
if (result.length <= 0) {
result = subParser.fromSrt(buffer.toString('utf8'))
if (result.length <= 0) {
result = subParser.fromSrt(buffer.toString('utf16le'))
if (result.length <= 0) {
error(`Cannot read file ${path}`)
}
}
}
return result
}
function containChinese (str) {
return /[\u4e00-\u9fa5]/.test(str)
}
function error (message) {
console.error(message)
}
node %~dp0\index.js %*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment