Skip to content

Commit 2e44b76

Browse files
authored
feat: ignore empty subtitles (#8)
* feat: ignore empty subtitles * chore: bump version
1 parent 0bc2963 commit 2e44b76

6 files changed

Lines changed: 43 additions & 21 deletions

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# 依赖文件夹
2+
node_modules/
3+
4+
# 编辑器和IDE配置
5+
.vscode/
6+
.idea/

analyzeMedia.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,27 @@ const getFFprobePath = () => {
1818
export const analyzeMedia = (file) => {
1919
console.log(`获取字幕信息...`);
2020
const ffprobePath = getFFprobePath();
21+
22+
/*
23+
TODO: 读取帧率输出
24+
ffprobe -v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate input.mkv | awk -F/ '{ print ($1 / $2) }'
25+
输出:23.976
26+
*/
27+
2128
return new Promise((resolve, reject) => {
2229
ffprobe(config.workdir + file, { path: ffprobePath })
2330
.then(function (info) {
24-
// console.log(info);
2531
const subTitles = info.streams.filter((stream) => stream.codec_type === 'subtitle').map(stream => ({
2632
index: stream.index,
2733
code: stream.tags.language.toLowerCase(),
2834
name: stream.tags.title ? stream.tags.title.toLowerCase() : '',
2935
duration: Math.round(stream.duration),
36+
frames: Number(stream.tags.NUMBER_OF_FRAMES) || 0
3037
}));
3138
console.log(`找到 ${subTitles.length} 条字幕。`);
3239
resolve(subTitles);
3340
})
3441
.catch(function (err) {
35-
// console.error(err);
3642
reject(err);
3743
});
3844
});

extractSub.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,19 @@ export const extractSub = (filename, targetSubs) => {
4141
.outputOptions(['-map', `0:${targetSubs[1].index}`, '-c', 'copy'])
4242
.run()
4343
.on('start', function (str) {
44-
console.log('转换任务开始~', str);
44+
console.log('正在提取字幕文件...', str);
4545
})
4646
.on('progress', function (progress) {
4747
const progressPercent = Math.round((timemarkToSeconds(progress.timemark) / duration) * 100);
4848
readline.cursorTo(process.stdout, 0);
49-
process.stdout.write(`进行中,完成${(progressPercent || 0)}%`);
49+
process.stdout.write(`字幕提取中,进度:${(progressPercent || 0)}%`);
5050
})
5151
.on('end', function (str) {
52-
console.log('转换任务完成!');
52+
console.log('\n字幕提取完成。');
5353
resolve([mainSrt, secondarySrt]);
5454
})
5555
.on('error', function (err) {
56-
console.log('转换任务出错:', err);
56+
console.log('字幕提取出错:', err);
5757
reject(err);
5858
});
5959
});

findSub.js

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,24 +59,34 @@ const findChiSub = (subTitles) => {
5959
* 9,subrip,eng
6060
* 10,subrip,eng,SDH
6161
* 23,subrip,eng,English[CC]
62-
* 如果同时有SDH和非SDH版本,选非SDH版本。
62+
* 选择策略:
63+
* 1. 过滤掉空字幕(只有当 NUMBER_OF_FRAMES 存在且 < 10 时才过滤)
64+
* 2. 如果同时有SDH和非SDH版本,选非SDH版本
65+
* 3. 按原始顺序选择第一个可用的字幕
6366
*/
6467
const findEngSub = (subTitles) => {
6568
const englishSubs = subTitles.filter(sub => sub.code === 'eng');
6669

6770
if (englishSubs.length === 0) return null;
68-
if (englishSubs.length === 1) return {
69-
index: englishSubs[0].index,
70-
duration: englishSubs[0].duration,
71-
};
72-
73-
// Filter out SDH subtitles if there are multiple English options
74-
const nonSDHSubs = englishSubs.filter(sub =>
75-
!sub.name.includes('sdh')
76-
);
7771

78-
// Return first non-SDH sub if available, otherwise first English sub
79-
const targetSub = nonSDHSubs[0] || englishSubs[0];
72+
// 过滤掉空字幕
73+
const nonEmpty = englishSubs.filter(sub => {
74+
const frames = Number(sub.frames);
75+
if (!frames) return true;
76+
return frames >= 10;
77+
});
78+
79+
const candidatePool = nonEmpty.length > 0 ? nonEmpty : englishSubs;
80+
81+
if (candidatePool.length === 0) return null;
82+
83+
// 多个英文字幕时,优先去除 SDH
84+
const nonSDHSubs = candidatePool.filter(sub => !sub.name.includes('sdh'));
85+
const finalPool = nonSDHSubs.length > 0 ? nonSDHSubs : candidatePool;
86+
87+
// 按原始顺序选择第一个可用的字幕
88+
const targetSub = finalPool[0];
89+
8090
return targetSub ? {
8191
index: targetSub.index,
8292
duration: targetSub.duration

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dual-subtitle",
3-
"version": "0.3.1",
3+
"version": "0.4.0",
44
"main": "index.js",
55
"type": "module",
66
"bin": {

0 commit comments

Comments
 (0)