/** * Video quality from lowest to highest */ export enum Resolution { HD4k, HD1080, HD720, SD384, SD480, SD360, Unknown } // https://en.wikipedia.org/wiki/Pirated_movie_release_types#DVD_and_VOD_ripping // https://en.wikipedia.org/wiki/Standard_(warez)#cite_note-txd2k9-13 /** * Types of releases from lowest quality to highest */ export enum ReleaseType { BluRay, WebDl, WebRip, WebCap, HDRip, DVDR, DVDRip, Unknown, // Unknown is better than cam tbh HDCAM, CAM } export enum VideoCodec { XviD, x264, x265, } export enum VideoCodecFlag { REMUX, HDR, HEVC } export enum AudioCodec { AC3, DD51, AAC71, Atmos71, TenBit } export interface ITorrentMetaInfo { containsOtherLanguage: boolean, resolution: Resolution, releaseType: ReleaseType, } /** * Determine meta-info from a torrent name */ export function parseMovieTorrentName(torrentName: string, title: string = "", year?: number) { // Split the meta info after the year if possible to make parsing more reliable let split = torrentName.split(new RegExp(`${year}|\\(${year}\\)`)); let metaInfo = split[split.length - 1]; title = split.length > 1 ? "" : title; // No need to check title in parsing if split correctly return { containsOtherLanguage: determineIfContainsOtherLanguages(torrentName, title), resolution: determineResolution(metaInfo, title), releaseType: determineReleaseType(metaInfo, title), } } /** * Examine the torrent name for language indicators */ function determineIfContainsOtherLanguages(torrentName: string, title: string) { let matches = torrentName.match(/\b(?:Hindi|Telugu|Ita|Italian|Spanish|Latino|Russian|Arabic|Dual|Multi)\b/gi); for (let match of matches ?? []) { if (title.indexOf(match) == -1) { return true; } } return false; } /** * Interpret the resolution string as an enum value */ function resolutionFromString(resolution: string) { switch(resolution.toUpperCase()) { case "4K": case "UHD": case "2160": return Resolution.HD4k; case "1080": return Resolution.HD1080; case "720": return Resolution.HD720; case "480": return Resolution.SD480; case "384": return Resolution.SD384; case "360": return Resolution.SD360; default: return Resolution.Unknown; } } /** * Determine the video resolution of the torrent */ function determineResolution(torrentName: string, title: string) { let matches = torrentName.match(/\b(?:2160|1080|720|480|384|360)p?|UltraHD|UHD|4K\b/gi); if (matches == null) { return Resolution.Unknown; } let resolution = matches[matches.length - 1]; // Make sure what was matched is not part of the title... if (matches.length == 1 && title.indexOf(resolution) != -1) { return Resolution.Unknown; } return resolutionFromString(resolution.replace(/p$/i, "")); } /** * Determine the release type of the torrent */ function determineReleaseType(torrentName: string, title: string) { let releaseTypeRegex: {[type: string]: RegExp} = { [ReleaseType.BluRay]: /\b(?:BR|Blu-Ray|BluRay|BDRip|BRRip|BDMV|BDR|BD25|BD50|BD5|BD9)\b/i, [ReleaseType.WebDl] : /\b(?:WEB.?DL|WEB-DLRip)\b/i, [ReleaseType.WebRip]: /\b(?:WEB.?Rip|WEB)\b/i, [ReleaseType.WebCap]: /\bWEB.?Cap\b/i, [ReleaseType.HDRip] : /\b(?:HC|HD.?Rip)\b/i, [ReleaseType.DVDR] : /\bDVD.?R|DVD-Full|Full-Rip|DVD.?5|DVD.?9\b/i, [ReleaseType.DVDRip]: /\bDVD.?Rip|DVD.?Mux/i, [ReleaseType.HDCAM] : /\b(?:TRUE|HD)CAM\b/i, [ReleaseType.CAM] : /\bCAM.?Rip\b/i, }; let matches: RegExpMatchArray | null; for (let type in releaseTypeRegex) { matches = torrentName.match(releaseTypeRegex[type]); if (!matches) { continue; } if (matches.length == 1 || title.indexOf(matches[matches.length - 1]) == -1) { return parseInt(type); } } return ReleaseType.Unknown; }