mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-08-04 19:21:33 -07:00
fix(anime): thread episode metadata through stream playback and fix seas
- Split anime browser stream titles into series/season/episode fields (episode-metadata.ts) instead of one joined string, so stats grouping, the mpv title, and the Jimaku/TsukiHime modals all get real values instead of a filename-derived "m3u8" - Fix AniList season resolver to walk through split-cour sequels and specials without counting them as a season, and to surface rate-limit/network failures instead of falling through to a wrong air-order guess - Add a Season field to the TsukiHime modal and include later seasons in its search query - Rewrite WebVTT subtitle tracks as SRT before handing them to alass, since alass has no VTT support and streams serve VTT - Update CHANGELOG and troubleshooting docs
This commit is contained in:
+29
-4
@@ -4,6 +4,7 @@ import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as childProcess from 'child_process';
|
||||
import { createLogger } from '../logger';
|
||||
import { splitSeasonFromTitle } from '../anime-bridge/episode-metadata';
|
||||
import {
|
||||
JimakuApiResponse,
|
||||
JimakuConfig,
|
||||
@@ -163,6 +164,28 @@ function matchEpisodeFromName(name: string): {
|
||||
};
|
||||
}
|
||||
|
||||
// Spelled-out labels. Streaming sources name episodes this way ("Episode 4"),
|
||||
// and the abbreviated `E04` pattern below cannot see them.
|
||||
const worded = name.match(/(?:^|[\s._-])episode\s*[.#]?\s*(\d{1,3})(?:\D|$)/i);
|
||||
if (worded && worded.index !== undefined) {
|
||||
return {
|
||||
season: null,
|
||||
episode: Number.parseInt(worded[1]!, 10),
|
||||
index: worded.index,
|
||||
confidence: 'medium',
|
||||
};
|
||||
}
|
||||
|
||||
const japanese = name.match(/第\s*(\d{1,3})\s*話/);
|
||||
if (japanese && japanese.index !== undefined) {
|
||||
return {
|
||||
season: null,
|
||||
episode: Number.parseInt(japanese[1]!, 10),
|
||||
index: japanese.index,
|
||||
confidence: 'medium',
|
||||
};
|
||||
}
|
||||
|
||||
const epOnly = name.match(/(?:^|[\s._-])E(?:P)?(\d{1,3})(?:\b|[\s._-])/i);
|
||||
if (epOnly && epOnly.index !== undefined) {
|
||||
return {
|
||||
@@ -229,12 +252,14 @@ export function parseMediaInfo(mediaPath: string | null): JimakuMediaInfo {
|
||||
titlePart = name.slice(0, parsed.index);
|
||||
}
|
||||
|
||||
const seasonFromDir = parsed.season ?? detectSeasonFromDir(normalizedMediaPath);
|
||||
const title = cleanupTitle(titlePart || name);
|
||||
// A season named in the title ("… Season 3") belongs in the season field, not
|
||||
// glued to the title — otherwise it is searched for as part of the name.
|
||||
const titleSeason = splitSeasonFromTitle(cleanupTitle(titlePart || name));
|
||||
const season = parsed.season ?? titleSeason.season ?? detectSeasonFromDir(normalizedMediaPath);
|
||||
|
||||
return {
|
||||
title,
|
||||
season: seasonFromDir,
|
||||
title: titleSeason.title,
|
||||
season,
|
||||
episode: parsed.episode,
|
||||
confidence: parsed.confidence,
|
||||
filename,
|
||||
|
||||
Reference in New Issue
Block a user