mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-08-17 00:18:41 -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:
@@ -148,6 +148,10 @@
|
||||
<span>Title</span>
|
||||
<input id="tsukihimeTitle" type="text" placeholder="Anime title" />
|
||||
</label>
|
||||
<label class="jimaku-field">
|
||||
<span>Season</span>
|
||||
<input id="tsukihimeSeason" type="number" min="1" placeholder="1" />
|
||||
</label>
|
||||
<label class="jimaku-field">
|
||||
<span>Episode</span>
|
||||
<input id="tsukihimeEpisode" type="number" min="1" placeholder="1" />
|
||||
|
||||
@@ -188,6 +188,7 @@ function createModalHarness(
|
||||
setAttribute: () => {},
|
||||
},
|
||||
tsukihimeTitleInput: { value: '' },
|
||||
tsukihimeSeasonInput: { value: '' },
|
||||
tsukihimeEpisodeInput: { value: '' },
|
||||
tsukihimeSearchButton: { addEventListener: () => {} },
|
||||
tsukihimeCloseButton: { addEventListener: () => {} },
|
||||
|
||||
@@ -191,16 +191,27 @@ export function createTsukihimeModal(
|
||||
});
|
||||
}
|
||||
|
||||
function readNumericInput(input: HTMLInputElement): number | null {
|
||||
if (!input.value) return null;
|
||||
const parsed = Number.parseInt(input.value, 10);
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
||||
}
|
||||
|
||||
function getSearchQuery(): string {
|
||||
const title = ctx.dom.tsukihimeTitleInput.value.trim();
|
||||
if (!title) return '';
|
||||
const episodeValue = ctx.dom.tsukihimeEpisodeInput.value
|
||||
? Number.parseInt(ctx.dom.tsukihimeEpisodeInput.value, 10)
|
||||
: null;
|
||||
if (episodeValue !== null && Number.isFinite(episodeValue)) {
|
||||
return `${title} ${String(episodeValue).padStart(2, '0')}`;
|
||||
const season = readNumericInput(ctx.dom.tsukihimeSeasonInput);
|
||||
const episode = readNumericInput(ctx.dom.tsukihimeEpisodeInput);
|
||||
// Season 1 is left out on purpose: releases of a first season almost never
|
||||
// put "S01" in the name, so adding it narrows the search to nothing.
|
||||
const parts = [title];
|
||||
if (season !== null && season > 1) {
|
||||
parts.push(`S${String(season).padStart(2, '0')}`);
|
||||
}
|
||||
return title;
|
||||
if (episode !== null) {
|
||||
parts.push(String(episode).padStart(2, '0'));
|
||||
}
|
||||
return parts.join(' ');
|
||||
}
|
||||
|
||||
async function performTsukihimeSearch(): Promise<void> {
|
||||
@@ -369,6 +380,7 @@ export function createTsukihimeModal(
|
||||
.getJimakuMediaInfo()
|
||||
.then(async (info: JimakuMediaInfo) => {
|
||||
ctx.dom.tsukihimeTitleInput.value = info.title || '';
|
||||
ctx.dom.tsukihimeSeasonInput.value = info.season ? String(info.season) : '';
|
||||
ctx.dom.tsukihimeEpisodeInput.value = info.episode ? String(info.episode) : '';
|
||||
|
||||
if (info.confidence === 'high' && info.title && info.episode) {
|
||||
|
||||
@@ -24,6 +24,7 @@ export type RendererDom = {
|
||||
|
||||
tsukihimeModal: HTMLDivElement;
|
||||
tsukihimeTitleInput: HTMLInputElement;
|
||||
tsukihimeSeasonInput: HTMLInputElement;
|
||||
tsukihimeEpisodeInput: HTMLInputElement;
|
||||
tsukihimeSearchButton: HTMLButtonElement;
|
||||
tsukihimeCloseButton: HTMLButtonElement;
|
||||
@@ -180,6 +181,7 @@ export function resolveRendererDom(): RendererDom {
|
||||
|
||||
tsukihimeModal: getRequiredElement<HTMLDivElement>('tsukihimeModal'),
|
||||
tsukihimeTitleInput: getRequiredElement<HTMLInputElement>('tsukihimeTitle'),
|
||||
tsukihimeSeasonInput: getRequiredElement<HTMLInputElement>('tsukihimeSeason'),
|
||||
tsukihimeEpisodeInput: getRequiredElement<HTMLInputElement>('tsukihimeEpisode'),
|
||||
tsukihimeSearchButton: getRequiredElement<HTMLButtonElement>('tsukihimeSearch'),
|
||||
tsukihimeCloseButton: getRequiredElement<HTMLButtonElement>('tsukihimeClose'),
|
||||
|
||||
Reference in New Issue
Block a user