/**
|
|
* 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 <ITorrentMetaInfo>{
|
|
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 <ReleaseType>parseInt(type);
|
|
}
|
|
}
|
|
return ReleaseType.Unknown;
|
|
}
|