Getting Started
Parsium is a blazingly fast medianame filename parser targeting TypeScript. It is built to consistently extract the most granular details from movie and TV show release filenames.
bolt Why Parsium?
- ✦ Dependency-free architecture
- ✦ Handles thousands of filenames per second
- ✦ Over 1,200+ unit test cases to ensure correctness
- ✦ First-class TypeScript with strict static guarantees
Installation
We recommend using preferred package manager (npm, pnpm, yarn or bun). Parsium requires Node.js version 22.0.0 or higher (or Bun/Deno).
pnpm add parsium-media Basic Usage
Pass any release filename to the parse function. The parser will immediately return a strongly typed object mapping out traits extracted from the name.
import { parse } from 'parsium-media';
// Analyze a title
const result = parse("The.Matrix.1999.1080p.BluRay.x264-YTS");
console.log(result.title); // "The Matrix"
console.log(result.year); // 1999
console.log(result.resolution); // "1080p" Options parse(filename, options)
Pass an options object as the second argument to parse() to enable additional output.
const result = parse('Movie.2024.1080p.mkv', { explain: true });
// result.explanation = [
// { extractor: 'resolution', value: '1080p', confidence: 1.0, ... },
// { extractor: 'year', value: 2024, confidence: 0.95, ... },
// ] const result = parse('Movie.2024.1080p.mkv', { fieldConfidence: true });
// result.fieldConfidence = {
// title: 0.8, contentType: 0.9, year: 0.95, resolution: 1.0
// } | Option | Type | Description |
|---|---|---|
| explain | boolean | Returns step-by-step extraction reasoning in result.explanation. |
| fieldConfidence | boolean | Returns per-field confidence scores (0–1) in result.fieldConfidence. |
API Reference ParseResult
Complete list of all properties returned by parse(). Only truthy values are included in the result by default.
| Property | Type | Description |
|---|---|---|
| title | string | The identified show or movie title. |
| altTitle | string | undefined | Alternate/original-language title from parentheses. |
| year | number | undefined | Four-digit release year if available. |
| contentType | 'movie' | 'series' | 'unknown' | Detected content type. |
| contentSubtype | 'anime' | undefined | Content subtype if detected (e.g. anime). |
| seasons | number[] | Array of season numbers (e.g. [1, 2]). |
| episodes | number[] | Array of episode numbers. |
| episodeTitle | string | undefined | Episode title if embedded in filename. |
| resolution | string | undefined | Resolution (1080p, 2160p, 720p, etc.). |
| source | string | undefined | Media source (BluRay, WEB-DL, HDTV, etc.). |
| codec | string | undefined | Video codec (x264, x265, HEVC, AV1, etc.). |
| hdr | string[] | undefined | HDR formats, atomic and ordered (DV, HDR10, HDR10+, HLG). e.g. ["DV","HDR10"]. |
| audio | string[] | undefined | Audio codecs/layers, atomic and ordered. e.g. ["TrueHD","Atmos"], ["DD+"]. |
| channels | string[] | undefined | Channel layouts, ordered (2.0, 5.1, 7.1, 7.1.4). e.g. ["5.1"]. |
| releaseGroup | string | undefined | Release group name (e.g. FLUX, YTS). |
| container | string | undefined | File container (mkv, mp4, avi, etc.). |
| languages | Language[] | Detected languages with code & label. |
| isSeasonPack | boolean | Whether this is a full season pack. |
| isRemux | boolean | Whether the file is a remux. |
| editions | string[] | undefined | Special editions (IMAX, Director's Cut, etc.). |
| streamingService | string | undefined | Streaming platform (Netflix, Amazon Prime Video, Disney+, etc.). |
| bitDepth | string | undefined | Color bit depth (8-bit, 10-bit, 12-bit). |
| frameRate | string | undefined | Frame rate when present (24fps, 60fps, etc.). |
| absoluteEpisode | number | undefined | Absolute episode number (common in anime). |
| absoluteEpisodeRange | { from, to } | undefined | Contiguous absolute episode range (anime batches). |
| episodeRange | { from, to } | undefined | Contiguous episode range (e.g. E01-E12). |
| date | string | undefined | Date-based episode (YYYY-MM-DD) for daily shows. |
| subtitleLanguages | Language[] | undefined | Languages detected as subtitles (VOSTFR, Sub, etc.). |
| isMultiSubtitle | boolean | undefined | True for multi-subtitle tracks (Multi Subs, MSub). |
| isCompleteSeries | boolean | True for complete series packs. |
| isBatchRelease | boolean | True for batch episode releases. |
| isMultiLanguage | boolean | True when MULTI or 3+ languages detected. |
| isDualAudio | boolean | True for dual audio releases. |
| isRepack | boolean | True for repacked releases. |
| isProper | boolean | True for proper releases. |
| is3D | boolean | True for 3D releases (3D, H-SBS, H-OU). |
| isHybrid | boolean | True for hybrid releases (combined sources). |
| isUpscaled | boolean | True when AI-upscaled (AI Upscale, Neural Upscale). |
CLI npx parsium-media
Run Parsium directly from the command line via npx, no installation required.
# Parse a single filename
npx parsium-media "The.Matrix.1999.1080p.BluRay.x264-GROUP.mkv"
# With step-by-step extraction reasoning
npx parsium-media --explain "Movie.2024.1080p.BluRay.x265-GROUP.mkv"
# JSON output (truthy fields only)
npx parsium-media --json "Movie.2024.mkv"
# Parse from a file (one filename per line)
npx parsium-media --file torrents.txt --json --progress | Flag | Description |
|---|---|
| --explain | Show debug explanation for each extraction |
| --confidence | Show per-field confidence scores |
| --json | Output as JSON (only present fields) |
| --json-full | Output as JSON (all fields including false/empty) |
| --file <path> | Read filenames from a file (one per line) |
| --progress | Show progress during batch parsing |
Plugin System Advanced
Extend the parser with custom extractors without modifying core code. Plugins add new extractors that run alongside the 15 built-in ones.
import { createParser } from 'parsium-media';
const parser = createParser({
plugins: [{
name: 'tracker-tags',
extractors: [{
name: 'tracker-meta',
priority: 8.5,
extract(ctx) {
const match = /\[(INTERNAL|FREELEECH)\]/i.exec(ctx.normalized);
if (!match) return null;
return {
value: { trackerTag: match[1].toUpperCase() },
consumed: [[match.index, match.index + match[0].length]],
confidence: 1.0,
};
},
}],
}],
});
const result = parser.parse('[INTERNAL] Movie.2024.mkv');
// result.trackerTag === 'INTERNAL' Built-in Extractor Priorities
Use fractional priorities (e.g. 9.5) to insert your extractors between built-ins. The title extractor runs last and claims unclaimed text.
| Priority | Extractor | Description |
|---|---|---|
| 1 | resolution | 1080p, 4K, 2160p |
| 2 | source | BluRay, WEB-DL, HDTV |
| 3 | codec | x264, x265, HEVC, AV1 |
| 3 | date | Date-based episodes (2025.01.15) |
| 3 | fps | Frame rate (24fps, 60fps) |
| 4 | audio | TrueHD, DTS-HD, AAC |
| 5 | hdr | HDR10, DV, HLG |
| 6 | language | Multi-language detection |
| 7 | year | Release year |
| 8 | edition | Director's Cut, Extended |
| 9 | misc | REPACK, PROPER, REMUX |
| 10 | season-episode | S01E02 patterns |
| 11 | anime-episode | Absolute episodes, batch |
| 12 | release-group | Trailing group name |
| 13 | title | Title by elimination |
HTTP API REST
Parsium exposes a lightweight HTTP API for non-Node.js consumers. Built with Hono, deployable to Vercel, Cloudflare Workers, Docker, or any Node.js host.
POST /v1/parse
Parse a single filename.
{
"filename": "The.Boys.S05E02.1080p.WEB.H264-TyHD.mkv",
"options": {
"explain": false,
"fieldConfidence": false
}
} {
"success": true,
"data": {
"title": "The Boys",
"contentType": "series",
"seasons": [5],
"episodes": [2],
"resolution": "1080p",
"codec": "H.264",
"releaseGroup": "TyHD",
"container": "mkv"
},
"meta": { "parseTimeMs": 0.6 }
} POST /v1/parse/batch
Parse multiple filenames in a single request (max 10).
{
"filenames": [
"Movie.2024.2160p.UHD.BluRay.x265-GROUP.mkv",
"Anime.S01E01.1080p.WEB.H264-Sub.mkv"
]
} info Rate Limiting
The HTTP API applies IP-based rate limiting at 50 requests/minute. For high-throughput needs, use the npm package directly.
Performance Tuning
Parsium processes thousands of filenames per second with zero dependencies. For high-throughput scenarios, use the cached parser.
import { createCachedParser } from 'parsium-media';
// LRU cache with 10,000 entries
const { parse, size, clear } = createCachedParser(10000);
const result = parse('Same.File.Again.mkv');
// Second call with same input is instant (cache hit) import { parseBatch } from 'parsium-media';
const results = parseBatch(filenames, {
onProgress: (completed, total) => {
console.log(`${completed}/${total}`);
},
}); tips_and_updates Tips
- ✦ Use
createCachedParser()when parsing recurring filenames (torrent clients, media servers) - ✦ Use
parseBatch()withonProgressfor UI feedback on large lists - ✦ Parsium is fully synchronous — no async overhead, no event loop blocking on single parses
- ✦ The browser bundle (
parsium.browser.js) is optimized for client-side use