subtitles-adjuster
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -9,3 +9,3 @@ #!/usr/bin/env node | ||
const ass2srt = require('../ass-to-srt'); | ||
const ass2srt = require('../utils/ass-to-srt'); | ||
const subtitlesAdjuster = require('../index'); | ||
@@ -20,3 +20,5 @@ | ||
const outputFilename = path.resolve( | ||
argv.o || argv.output || `${(draftFileName || '').replace(/\.(srt|ass)$/, '.fixed.srt')}`, | ||
argv.o || | ||
argv.output || | ||
`${(draftFileName || '').replace(/\.(srt|ass)$/, '.fixed.srt')}` | ||
); | ||
@@ -31,7 +33,11 @@ | ||
if (!baseFileName) { | ||
throw new Error('[Error] Base subtitle filename is required. Please use the -b or --base flag'); | ||
throw new Error( | ||
'[Error] Base subtitle filename is required. Please use the -b or --base flag' | ||
); | ||
} | ||
if (!draftFileName) { | ||
throw new Error('[Error] Draft subtitle filename is required. Please use the -b or --draft flag'); | ||
throw new Error( | ||
'[Error] Draft subtitle filename is required. Please use the -b or --draft flag' | ||
); | ||
} | ||
@@ -45,3 +51,3 @@ | ||
Not Support (不支持的文件): | ||
${unsuportFiles.join('\n')}`, | ||
${unsuportFiles.join('\n')}` | ||
); | ||
@@ -55,7 +61,7 @@ } | ||
baseFile, | ||
baseFileEncode || jschardet.detect(baseFile).encoding || 'utf8', | ||
baseFileEncode || jschardet.detect(baseFile).encoding || 'utf8' | ||
); | ||
let draftSubtitle = iconv.decode( | ||
draftFile, | ||
draftFileEncode || jschardet.detect(draftFile).encoding || 'utf8', | ||
draftFileEncode || jschardet.detect(draftFile).encoding || 'utf8' | ||
); | ||
@@ -62,0 +68,0 @@ |
77
index.js
@@ -0,5 +1,15 @@ | ||
/* | ||
* @Author: rpsh myrpsh@gmail.com | ||
* @Date: 2022-06-20 23:02:14 | ||
* @LastEditors: rpsh myrpsh@gmail.com | ||
* @LastEditTime: 2022-06-27 00:05:53 | ||
* @FilePath: /subtitles-adjuster/index.js | ||
* @Description: 自动校准字幕时间轴 | ||
*/ | ||
const lodash = require('lodash'); | ||
const { SubtitleTime } = require('subtitle-time'); | ||
const { default: stringSimilarity } = require('string-similarity-js'); | ||
const srtParser = require('./srt-parser'); | ||
const srtParser = require('./utils/srt-parser'); | ||
const checkBlacklist = require('./utils/check-blacklist'); | ||
@@ -14,2 +24,3 @@ // 校准字幕 | ||
let lag = 0; // 记录两个字幕之间的时间差距,当两个字幕不能匹配时候,使用这个 lag 自动调整时间 | ||
let matchFlag = true; // 标记是否有不匹配的字幕 | ||
@@ -26,4 +37,6 @@ draftSubtitles.forEach((item, index) => { | ||
index: j, | ||
matchFlag, | ||
}); | ||
console.log(`${j}/${i}/${matches[matches.length - 1]}`); | ||
if (i !== null) { | ||
@@ -38,2 +51,3 @@ // 先记录下来时间差,以备后续使用 | ||
j = i + 1; | ||
matchFlag = true; | ||
} else { | ||
@@ -43,2 +57,4 @@ // 推测调整没找到匹配字幕的时间偏移 | ||
item.endTime = adjustTime(item.endTime, lag); | ||
matchFlag = false; | ||
} | ||
@@ -59,11 +75,21 @@ } else { | ||
function findSimilarSubtitle(options) { | ||
const { text, baseSubtitles, index = 0, counter = 0 } = options; | ||
const { text, baseSubtitles, index = 0, counter = 0, matchFlag } = options; | ||
// 超过字幕条数,或者,查找超过50条后,则认为没有相似的字幕 | ||
if (index >= baseSubtitles.length || counter > 50) { | ||
if (index >= baseSubtitles.length || counter >= 50) { | ||
return null; | ||
} | ||
// 相似度超过 0.9 的即认为是同一条 | ||
if (stringSimilarity(text, baseSubtitles[index].text.replace(/\n/g, ' ')) >= 0.9) { | ||
// 相似度超过 0.85 的即认为是同一条 | ||
if ( | ||
stringSimilarity( | ||
text, | ||
baseSubtitles[index].text | ||
.replace(/\n/g, ' ') | ||
.replace(/\[\s?\w+\s?\]/, '') | ||
.replace(/\(\s?\w+\s?\)/, '') | ||
.replace(/^[a-zA-z'\. ]+:/, '') | ||
.replace(/^\s+/, '') | ||
) >= 0.85 | ||
) { | ||
return index; | ||
@@ -81,3 +107,6 @@ } else { | ||
function clacTimeLag(time1, time2) { | ||
return new SubtitleTime(time1, 'srt').to('second') - new SubtitleTime(time2, 'srt').to('second'); | ||
return ( | ||
new SubtitleTime(time1, 'srt').to('second') - | ||
new SubtitleTime(time2, 'srt').to('second') | ||
); | ||
} | ||
@@ -87,3 +116,6 @@ | ||
function adjustTime(time, lag) { | ||
return new SubtitleTime(new SubtitleTime(time, 'srt').to('second') + lag, 'second').to('srt'); | ||
return new SubtitleTime( | ||
new SubtitleTime(time, 'srt').to('second') + lag, | ||
'second' | ||
).to('srt'); | ||
} | ||
@@ -99,5 +131,34 @@ | ||
function parseSubtitle(file) { | ||
return srtParser.fromSrt(file); | ||
const subtitles = srtParser.fromSrt(file); | ||
return tidySubtitles(subtitles); | ||
} | ||
// 整理字幕,去除无用的字幕 | ||
function tidySubtitles(subtitles) { | ||
let result = []; | ||
let i = 1; | ||
subtitles.forEach((item) => { | ||
if (checkBlacklist(item.text) || !item.text) { | ||
return true; | ||
} | ||
result.push({ | ||
...item, | ||
id: `${i}`, | ||
text: item.text.replace(/{\\[^}]*}/g, ''), // 移除字幕中的特殊样式 | ||
start: new SubtitleTime(item.startTime, 'srt').to('second'), | ||
}); | ||
i++; | ||
}); | ||
// 重新按时间排序 | ||
result = lodash.orderBy(result, ['start'], ['asc']); | ||
result.forEach((item, index) => { | ||
item.id = `${index + 1}`; | ||
}); | ||
return result; | ||
} | ||
module.exports = subtitlesAdjuster; |
{ | ||
"name": "subtitles-adjuster", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Auto adjust the timeline of bilingual subtitles with the base subtitles. (根据基准字幕自动校正中英双语字幕的时间轴)", | ||
@@ -24,11 +24,11 @@ "main": "index.js", | ||
"ass-to-srt": "^1.2.1", | ||
"iconv-lite": "^0.6.3", | ||
"jschardet": "^3.0.0", | ||
"lodash": "^4.17.21", | ||
"srt-parser-2": "^1.1.7", | ||
"string-similarity-js": "^2.1.4", | ||
"subtitle-time": "^1.0.6" | ||
"subtitle-time": "^1.0.6", | ||
"yargs": "^15.4.1" | ||
}, | ||
"devDependencies": { | ||
"iconv-lite": "^0.6.3", | ||
"yargs": "^15.4.1" | ||
} | ||
"devDependencies": {} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13231
0
9
331
8
3
1
+ Addediconv-lite@^0.6.3
+ Addedlodash@^4.17.21
+ Addedyargs@^15.4.1
+ Addedansi-regex@5.0.1(transitive)
+ Addedansi-styles@4.3.0(transitive)
+ Addedcamelcase@5.3.1(transitive)
+ Addedcliui@6.0.0(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addeddecamelize@1.2.0(transitive)
+ Addedemoji-regex@8.0.0(transitive)
+ Addedfind-up@4.1.0(transitive)
+ Addedget-caller-file@2.0.5(transitive)
+ Addediconv-lite@0.6.3(transitive)
+ Addedis-fullwidth-code-point@3.0.0(transitive)
+ Addedlocate-path@5.0.0(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedp-limit@2.3.0(transitive)
+ Addedp-locate@4.1.0(transitive)
+ Addedp-try@2.2.0(transitive)
+ Addedpath-exists@4.0.0(transitive)
+ Addedrequire-directory@2.1.1(transitive)
+ Addedrequire-main-filename@2.0.0(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedset-blocking@2.0.0(transitive)
+ Addedstring-width@4.2.3(transitive)
+ Addedstrip-ansi@6.0.1(transitive)
+ Addedwhich-module@2.0.1(transitive)
+ Addedwrap-ansi@6.2.0(transitive)
+ Addedy18n@4.0.3(transitive)
+ Addedyargs@15.4.1(transitive)
+ Addedyargs-parser@18.1.3(transitive)