refactor(video): uniformiser classification et routage par section
CI / build-and-test (push) Successful in 14m9s
CI / build-and-test (push) Successful in 14m9s
Source unique de classification (video-kind.ts) + politique de section centralisee (section-policy.ts). Les composants ne portent plus de seuils ni de regles de type maison. - section-policy.ts: sectionAccepts / routeForVideo / shortsFeedAccepts / isPlayable + classifyOnce (enrichissement _kind a l'ingestion) - watch-short: separe classification (shortsFeedAccepts) et jouabilite (isPlayable: allowEmbed DM, live/channel Twitch, Rumble 404); supprime le seuil Rumble 90 s et l'import YOUTUBE_SHORT_MAX_SECONDS du composant - home: filtre sectionAccepts(...,'home') (plus de shorts dans le trending), routeForVideo, pagination bouclee (min 20, max 5 iterations) - themes: _kind pre-calcule une fois, sectionAccepts, capacites live lues depuis le registre providers (fin de LIVE_PROVIDERS codes en dur) - video-kind: helpers isNativeVerticalProvider / hasKnownDuration - routes: alias /shorts/:id et /live/:id pour routeForVideo - tests: section-policy.spec.ts + video-kind.spec.ts etendus; npm run test:section
This commit is contained in:
@@ -24,6 +24,10 @@ export interface ClassifiableVideo {
|
||||
isLive?: boolean | null;
|
||||
width?: number | null;
|
||||
height?: number | null;
|
||||
videoId?: string | null;
|
||||
id?: string | null;
|
||||
/** Métadonnées brutes provider (ex. Dailymotion `allowEmbed`). */
|
||||
raw?: { allowEmbed?: boolean } | null;
|
||||
}
|
||||
|
||||
export const SHORT_MAX_SECONDS = 75;
|
||||
@@ -32,6 +36,25 @@ export const VERTICAL_SHORT_MAX_SECONDS = 90;
|
||||
// ponytail: ratio 0.8 arbitré, 0.75 si de faux carrés Instagram apparaissent.
|
||||
export const VERTICAL_MAX_RATIO = 0.8;
|
||||
|
||||
/**
|
||||
* Fournisseurs à production nativement verticale dont le scraper renvoie
|
||||
* souvent une durée inconnue (0). La tolérance « durée inconnue » du flux
|
||||
* Shorts s'appuie sur cette liste, PAS sur une règle de type (cf.
|
||||
* `shortsFeedAccepts` dans section-policy.ts).
|
||||
*/
|
||||
export const NATIVE_VERTICAL_PROVIDERS = new Set(['rumble', 'odysee']);
|
||||
|
||||
/** Le provider est-il nativement vertical (flux Shorts dédié) ? */
|
||||
export function isNativeVerticalProvider(provider?: string | null): boolean {
|
||||
return NATIVE_VERTICAL_PROVIDERS.has(String(provider || '').toLowerCase());
|
||||
}
|
||||
|
||||
/** Durée connue = nombre strictement positif (0 / null / undefined = inconnu). */
|
||||
export function hasKnownDuration(v: ClassifiableVideo | null | undefined): boolean {
|
||||
const d = Number((v as { duration?: unknown })?.duration ?? 0);
|
||||
return Number.isFinite(d) && d > 0;
|
||||
}
|
||||
|
||||
function numOrZero(v: unknown): number {
|
||||
const n = Number(v);
|
||||
return Number.isFinite(n) && n > 0 ? n : 0;
|
||||
|
||||
Reference in New Issue
Block a user