955 lines
24 KiB
JavaScript
955 lines
24 KiB
JavaScript
|
|
class Mediainfo {
|
|
constructor() {
|
|
if (this instanceof Mediainfo) {
|
|
throw Error('A static class cannot be instantiated.');
|
|
}
|
|
}
|
|
|
|
static audioCodecs = [
|
|
{
|
|
name: "HE-AAC",
|
|
match: {
|
|
codec_id: /^(A_)?AAC\/MPEG4\/LC\/SBR/
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "AAC-LC",
|
|
match: {
|
|
codec_id: /^(A_)?AAC/,
|
|
format_profile: "LC"
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "HE-AAC",
|
|
match: {
|
|
codec_id: /^(A_)?AAC/,
|
|
format_profile: /HE-AAC/
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "HE-AAC",
|
|
match: {
|
|
codec_id: /^(A_)?AAC/,
|
|
commercial_settings: /HE-AAC/
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "HE-AAC",
|
|
match: {
|
|
format: "AAC LC SBR",
|
|
codec_id: /^(A_)?AAC/
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "HE-AAC",
|
|
match: {
|
|
codec_id: "mp4a-40-5"
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "AAC-LC",
|
|
match: {
|
|
codec_id: /^(A_AAC-2|mp4a-40-2|AAC LC)$/
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "AAC-LC",
|
|
match: {
|
|
format: "AAC LC"
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
|
|
{
|
|
name: "AAC-Main",
|
|
match: {
|
|
codec_id: "A_AAC-1"
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "AAC-Main",
|
|
match: {
|
|
codec_id: /^(A_)?AAC/,
|
|
format_profile: "Main"
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "AAC-Main",
|
|
match: {
|
|
codec_id: /^(A_)?AAC/,
|
|
format_profile: "Main"
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
{
|
|
name: "AAC",
|
|
match: {
|
|
codec_id: /^(A_)?AAC/
|
|
},
|
|
legacy: "AAC"
|
|
},
|
|
|
|
{
|
|
name: "AC3",
|
|
match: {
|
|
codec_id: /^(A_)?AC-?3$/i
|
|
},
|
|
legacy: "AC3"
|
|
},
|
|
|
|
{
|
|
name: "Opus",
|
|
match: {
|
|
codec_id: /^(A_)?OPUS/i
|
|
},
|
|
legacy: "Opus",
|
|
open: true
|
|
},
|
|
|
|
{
|
|
name: "Vorbis",
|
|
match: {
|
|
codec_id: /^(A_)?VORBIS/i
|
|
},
|
|
legacy: "Vorbis",
|
|
open: true
|
|
},
|
|
|
|
{
|
|
name: "MP1",
|
|
match: {
|
|
codec_id: /^(MP1|A_MPEG\/L1)$/i
|
|
},
|
|
legacy: "MP1"
|
|
},
|
|
|
|
{
|
|
name: "MP1",
|
|
match: {
|
|
format: "MPEG Audio",
|
|
format_profile: "Layer 1"
|
|
},
|
|
legacy: "MP1"
|
|
},
|
|
|
|
{
|
|
name: "MP2",
|
|
match: {
|
|
codec_id: /^(MP2|A_MPEG\/L2)$/i
|
|
},
|
|
legacy: "MP2"
|
|
},
|
|
|
|
{
|
|
name: "MP2",
|
|
match: {
|
|
format: "MPEG Audio",
|
|
format_profile: "Layer 2"
|
|
},
|
|
legacy: "MP2"
|
|
},
|
|
|
|
{
|
|
name: "MP3",
|
|
match: {
|
|
codec_id: /^(MP3|A_MPEG\/L3)$/i
|
|
},
|
|
legacy: "MP3",
|
|
open: true //Patents expired
|
|
},
|
|
|
|
{
|
|
name: "MP3",
|
|
match: {
|
|
format: "MPEG Audio",
|
|
format_profile: "Layer 3"
|
|
},
|
|
legacy: "MP3",
|
|
open: true //Patents expired
|
|
},
|
|
|
|
{
|
|
name: "WMA",
|
|
match: {
|
|
codec_id: /^(A_)?WMA/i
|
|
},
|
|
legacy: "WMA",
|
|
},
|
|
|
|
{
|
|
name: "WMA",
|
|
match: {
|
|
format: /^(A_)?WMA/i
|
|
},
|
|
legacy: "WMA",
|
|
},
|
|
|
|
{
|
|
name: "ALAC",
|
|
match: {
|
|
codec_id: /^(A_)?ALAC/i
|
|
},
|
|
legacy: "ALAC",
|
|
lossless: true,
|
|
open: true
|
|
},
|
|
|
|
{
|
|
name: "TrueAudio",
|
|
match: {
|
|
codec_id: /^(A_)?TTA/
|
|
},
|
|
legacy: "TTA",
|
|
lossless: true,
|
|
open: true
|
|
},
|
|
|
|
{
|
|
name: "RealAudio 14.4",
|
|
match: {
|
|
codec_id: /^((A_)?REAL\/)?14_4/i
|
|
},
|
|
legacy: "RealAudio"
|
|
},
|
|
|
|
{
|
|
name: "RealAudio 28.8",
|
|
match: {
|
|
codec_id: /^((A_)?REAL\/)?28_8/i
|
|
},
|
|
legacy: "RealAudio"
|
|
},
|
|
|
|
{
|
|
name: "RealAudio ATRAC3",
|
|
match: {
|
|
codec_id: /^((A_)?REAL\/)?ATRC/i
|
|
},
|
|
legacy: "RealAudio"
|
|
},
|
|
|
|
{
|
|
name: "RealAudio COOK",
|
|
match: {
|
|
codec_id: /^((A_)?REAL\/)?COOK/i
|
|
},
|
|
legacy: "RealAudio"
|
|
},
|
|
|
|
{
|
|
name: "RealAudio SIPR",
|
|
match: {
|
|
codec_id: /^((A_)?REAL\/)?SIPR/i
|
|
},
|
|
legacy: "RealAudio"
|
|
},
|
|
|
|
{
|
|
name: "WavPack",
|
|
match: {
|
|
codec_id: "A_WAVPACK4"
|
|
},
|
|
legacy: "WAV",
|
|
lossless: true,
|
|
open: true
|
|
},
|
|
|
|
{
|
|
name: "FLAC",
|
|
match: {
|
|
codec_id: /^(A_)?FLAC/i
|
|
},
|
|
legacy: "FLAC",
|
|
lossless: true,
|
|
open: true
|
|
},
|
|
|
|
{
|
|
name: "PCM",
|
|
match: {
|
|
format: /^PCM$/i
|
|
},
|
|
legacy: "PCM",
|
|
lossless: true,
|
|
open: true
|
|
},
|
|
|
|
{
|
|
name: "PCM",
|
|
match: {
|
|
codec_id: /^(A_)?PCM/
|
|
},
|
|
legacy: "PCM",
|
|
lossless: true,
|
|
open: true
|
|
},
|
|
|
|
{
|
|
name: "E-AC3",
|
|
match: {
|
|
codec_id: /(A_)?E-?AC-?3/,
|
|
number_of_dynamic_objects: null
|
|
},
|
|
legacy: "AC3"
|
|
|
|
},
|
|
{
|
|
name: "E-AC3 Atmos",
|
|
match: {
|
|
codec_id: /(A_)?E-?AC-?3/,
|
|
number_of_dynamic_objects: /^[0-9]+$/
|
|
},
|
|
legacy: "AC3"
|
|
|
|
},
|
|
{
|
|
name: "TrueHD Atmos",
|
|
match: {
|
|
codec_id: /^(A_)?TRUEHD/i,
|
|
number_of_dynamic_objects: /^[0-9]+$/
|
|
},
|
|
legacy: "TrueHD",
|
|
lossless: true
|
|
},
|
|
{
|
|
name: "TrueHD Atmos",
|
|
match: {
|
|
codec_id: /^(A_)?TRUEHD/i,
|
|
channel_positions: /^Object Based/
|
|
},
|
|
legacy: "TrueHD",
|
|
lossless: true
|
|
},
|
|
{
|
|
name: "TrueHD",
|
|
match: {
|
|
codec_id: /^(A_)?TRUEHD/i,
|
|
number_of_dynamic_objects: null
|
|
},
|
|
legacy: "TrueHD",
|
|
lossless: true
|
|
},
|
|
{
|
|
name: "TrueHD",
|
|
match: {
|
|
codec_id: "MLP FBA",
|
|
commercial_name: /TrueHD/,
|
|
number_of_dynamic_objects: null
|
|
},
|
|
legacy: "TrueHD",
|
|
lossless: true
|
|
},
|
|
{
|
|
name: "TrueHD Atmos",
|
|
match: {
|
|
format: /^AC-3 MLP FBA/,
|
|
commercial_name: /TrueHD/,
|
|
number_of_dynamic_objects: /^[0-9]+$/
|
|
},
|
|
legacy: "TrueHD",
|
|
lossless: true
|
|
},
|
|
{
|
|
name: "TrueHD",
|
|
match: {
|
|
format: /^AC-3 MLP FBA/,
|
|
commercial_name: /TrueHD/,
|
|
number_of_dynamic_objects: null
|
|
},
|
|
legacy: "TrueHD",
|
|
lossless: true
|
|
},
|
|
|
|
{
|
|
name: "DTS:X MA",
|
|
match: {
|
|
codec_id: /^(A_)?DTS$/,
|
|
format: "DTS XLL X",
|
|
channels_original: "Object Based"
|
|
},
|
|
legacy: "DTS-HD MA",
|
|
lossless: true
|
|
},
|
|
{
|
|
name: "DTS-HD MA",
|
|
match: {
|
|
codec_id: /^(A_)?DTS$/,
|
|
format: "DTS XLL",
|
|
channels_original: null,
|
|
},
|
|
legacy: "DTS-HD MA",
|
|
lossless: true
|
|
},
|
|
{
|
|
name: "DTS-HD",
|
|
match: {
|
|
codec_id: /^(A_)?DTS$/,
|
|
format: "DTS XBR",
|
|
},
|
|
legacy: "DTS-HD"
|
|
},
|
|
{
|
|
name: "DTS",
|
|
match: {
|
|
codec_id: /^(A_)?DTS$/,
|
|
format: "DTS",
|
|
format_profile: null,
|
|
},
|
|
legacy: "DTS"
|
|
},
|
|
{
|
|
name: "DTS",
|
|
match: {
|
|
codec_id: /^(A_)?DTS$/,
|
|
format: "DTS",
|
|
format_profile: null,
|
|
},
|
|
legacy: "DTS"
|
|
},
|
|
{
|
|
name: "DTS-ES",
|
|
match: {
|
|
codec_id: /^(A_)?DTS$/,
|
|
format: /^(DTS )?ES/,
|
|
},
|
|
legacy: "DTS-ES"
|
|
},
|
|
{
|
|
name: "DTS-HD MA",
|
|
match: {
|
|
codec_id: /^(A_)?DTS$/,
|
|
format_profile: /^MA/,
|
|
channels_original: null,
|
|
},
|
|
legacy: "DTS-HD MA",
|
|
lossless: true
|
|
},
|
|
{ //Old way of identifying
|
|
name: "DTS-ES",
|
|
match: {
|
|
codec_id: /^(A_)?DTS$/,
|
|
format_profile: /^(DTS )?ES/,
|
|
},
|
|
legacy: "DTS-ES"
|
|
},
|
|
{ //Old way of identifying
|
|
name: "DTS-HD MA",
|
|
match: {
|
|
codec_id: /^(A_)?DTS$/,
|
|
format_profile: "MA / Core",
|
|
channels_original: null,
|
|
},
|
|
legacy: "DTS-HD MA",
|
|
lossless: true
|
|
},
|
|
{ //Even Older way of identifying
|
|
name: "DTS-HD MA",
|
|
match: {
|
|
codec_id: /^((A_)?DTS|DTS ES XLL)/,
|
|
commercial_name: "DTS-HD Master Audio",
|
|
channels_original: null,
|
|
},
|
|
legacy: "DTS-HD MA",
|
|
lossless: true
|
|
}
|
|
];
|
|
|
|
static videoCodecs = [
|
|
{
|
|
name: "MPEG-1",
|
|
match: {
|
|
codec_id: "V_MPEG1",
|
|
},
|
|
legacy: "MPEG-1/2"
|
|
},
|
|
{
|
|
name: "MPEG-2",
|
|
match: {
|
|
codec_id: "V_MPEG2",
|
|
},
|
|
legacy: "MPEG-1/2"
|
|
},
|
|
{
|
|
name: "MPEG-$version",
|
|
match: {
|
|
format: "MPEG Video",
|
|
format_version: /^Version (?<version>[12])$/,
|
|
},
|
|
legacy: "MPEG-1/2"
|
|
},
|
|
|
|
{
|
|
name: "VC-1 $codec",
|
|
match: {
|
|
codec_id: /^(V_MS\/VFW\/FOURCC \/ )?((?<codec>WMV3|WMVA|WVC1)|VC-?1)/,
|
|
bit_depth: "8 bits"
|
|
},
|
|
legacy: "VC-1"
|
|
},
|
|
|
|
{
|
|
name: "DivX 5",
|
|
match: {
|
|
codec_id: /(^V_MPEG4\/ISO\/ASP|DX50)$/,
|
|
},
|
|
legacy: "DivX"
|
|
},
|
|
|
|
{
|
|
name: "DivX 5",
|
|
match: {
|
|
codec_id: /^(V_MS\/VFW\/FOURCC \/ )?DX50/,
|
|
},
|
|
legacy: "DivX"
|
|
},
|
|
|
|
{
|
|
name: "DivX 4",
|
|
match: {
|
|
codec_id: /^(V_MS\/VFW\/FOURCC \/ )?DIVX/,
|
|
},
|
|
legacy: "DivX"
|
|
},
|
|
|
|
{
|
|
name: "DivX 4",
|
|
match: {
|
|
codec_id: /^V_MPEG4\/ISO\/SP$/,
|
|
},
|
|
legacy: "DivX"
|
|
},
|
|
|
|
{
|
|
name: "DivX 3",
|
|
match: {
|
|
codec_id: /(^V_MPEG4\/MS\/V3|DIV3)$/,
|
|
},
|
|
legacy: "DivX"
|
|
},
|
|
|
|
{
|
|
name: "XviD",
|
|
match: {
|
|
codec_id: /^V_MS\/VFW\/FOURCC \/ (XVID|mp4v)/i,
|
|
},
|
|
legacy: "XviD"
|
|
},
|
|
|
|
{
|
|
name: "XviD",
|
|
match: {
|
|
codec_id: /(^V_MPEG4\/ISO\/ASP|XVID)$/,
|
|
},
|
|
legacy: "XviD"
|
|
},
|
|
|
|
{
|
|
name: "RealVideo 1",
|
|
match: {
|
|
codec_id: /^((V_)?REAL\/)?RV10/i
|
|
},
|
|
legacy: "RealVideo"
|
|
},
|
|
|
|
{
|
|
name: "RealVideo G2",
|
|
match: {
|
|
codec_id: /^((V_)?REAL\/)?RV20/i
|
|
},
|
|
legacy: "RealVideo"
|
|
},
|
|
|
|
{
|
|
name: "RealVideo 3",
|
|
match: {
|
|
codec_id: /^((V_)?REAL\/)?RV30/i
|
|
},
|
|
legacy: "RealVideo"
|
|
},
|
|
|
|
{
|
|
name: "RealVideo 4",
|
|
match: {
|
|
codec_id: /^((V_)?REAL\/)?RV40/i
|
|
},
|
|
legacy: "RealVideo"
|
|
},
|
|
|
|
{
|
|
name: "h264 $chroma",
|
|
match: {
|
|
codec_id: /^(V_MPEG4\/ISO\/AVC|avc1|AVC|V_MS\/VFW\/FOURCC \/ H264)$/,
|
|
bit_depth: "8 bits",
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "h264"
|
|
},
|
|
|
|
{
|
|
name: "h264 $bitDepth-bit $chroma",
|
|
match: {
|
|
codec_id: /^(V_MPEG4\/ISO\/AVC|avc1|V_MS\/VFW\/FOURCC \/ H264)$/,
|
|
bit_depth: /^(?<bitDepth>10) bits/,
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "h264 $bitDepth-bit"
|
|
},
|
|
|
|
{
|
|
name: "h264 $chroma",
|
|
match: {
|
|
codec_id: /^(V_MPEG4\/ISO\/AVC|avc1|AVC|V_MS\/VFW\/FOURCC \/ H264)$/,
|
|
resolution: "24 bits",
|
|
colorimetry: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "h264"
|
|
},
|
|
|
|
{
|
|
name: "h264 10-bit $chroma",
|
|
match: {
|
|
codec_id: /^(V_MPEG4\/ISO\/AVC|avc1|V_MS\/VFW\/FOURCC \/ H264)$/,
|
|
resolution: /^30 bits/,
|
|
colorimetry: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "h264 $bitDepth-bit"
|
|
},
|
|
|
|
{
|
|
name: "Dirac",
|
|
match: {
|
|
codec_id: /^(V_)?DIRAC/i
|
|
},
|
|
legacy: "Dirac",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "Snow",
|
|
match: {
|
|
codec_id: /^(V_)?SNOW/i
|
|
},
|
|
legacy: "Snow",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "Theora",
|
|
match: {
|
|
codec_id: /^(V_)?THEORA/i
|
|
},
|
|
legacy: "Theora",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "VP6",
|
|
match: {
|
|
codec_id: /^(V_)?VP6/i
|
|
},
|
|
legacy: "VP6",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "VP6",
|
|
match: {
|
|
format: /^VP6$/i
|
|
},
|
|
legacy: "VP6",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "VP8 $chroma",
|
|
match: {
|
|
codec_id: /^(V_)?VP8/i,
|
|
bit_depth: "8 bits",
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "VP8",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "VP8 $bitDepth-bit $chroma",
|
|
match: {
|
|
codec_id: /^(V_)?VP8/i,
|
|
bit_depth: /^(?<bitDepth>10|12) bits/,
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "VP8",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "VP9 $chroma",
|
|
match: {
|
|
codec_id: /^(V_)?VP9/i,
|
|
bit_depth: "8 bits",
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "VP9",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "VP9 $bitDepth-bit $chroma",
|
|
match: {
|
|
codec_id: /^(V_)?VP9/i,
|
|
bit_depth: /^(?<bitDepth>10|12) bits/,
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "VP9",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "AV1 $chroma",
|
|
match: {
|
|
codec_id: /^((V_)?AV1$|av01)/i,
|
|
bit_depth: "8 bits",
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "AV1",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "AV1 $bitDepth-bit $chroma",
|
|
match: {
|
|
codec_id: /^((V_)?AV1$|av01)/i,
|
|
bit_depth: /^(?<bitDepth>10|12) bits/,
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "AV1",
|
|
open: true,
|
|
},
|
|
|
|
{
|
|
name: "h265 $chroma",
|
|
match: {
|
|
format: "HEVC",
|
|
bit_depth: "8 bits",
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "h265"
|
|
},
|
|
|
|
{
|
|
name: "h265 $bitDepth-bit $chroma",
|
|
match: {
|
|
format: "HEVC",
|
|
bit_depth: /^(?<bitDepth>10|12) bits/,
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "h265 $bitDepth-bit"
|
|
},
|
|
|
|
{
|
|
name: "h265 $chroma",
|
|
match: {
|
|
codec_id: /^(V_MPEGH\/ISO\/HEVC|hvc1|hev1)$/,
|
|
bit_depth: "8 bits",
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "h265"
|
|
},
|
|
|
|
{
|
|
name: "h265 $bitDepth-bit $chroma",
|
|
match: {
|
|
codec_id: /^(V_MPEGH\/ISO\/HEVC|hvc1|hev1)$/,
|
|
bit_depth: /^(?<bitDepth>10|12) bits/,
|
|
chroma_subsampling: /^(4:2:0|(?<chroma>[0-9]:[0-9]:[0-9]))/
|
|
},
|
|
legacy: "h265 $bitDepth-bit"
|
|
},
|
|
|
|
|
|
{ //Fallback
|
|
name: "h265",
|
|
match: {
|
|
codec_id: /^(V_MPEGH\/ISO\/HEVC|hvc1|hev1)$/,
|
|
bit_depth: null,
|
|
},
|
|
legacy: "h265"
|
|
},
|
|
|
|
{ //Fallback
|
|
name: "h265 $bitDepth-bit",
|
|
match: {
|
|
codec_id: /^(V_MPEGH\/ISO\/HEVC|hvc1|hev1)$/,
|
|
bit_depth: /^(?<bitDepth>10|12) bits/,
|
|
chroma_subsampling: null
|
|
},
|
|
legacy: "h265 $bitDepth-bit"
|
|
},
|
|
|
|
{
|
|
name: "FOURCC-$fourcc",
|
|
match: {
|
|
codec_id: /^V_MS\/VFW\/FOURCC \/ (?<fourcc>.{4})$/,
|
|
},
|
|
legacy: "$fourcc"
|
|
},
|
|
];
|
|
|
|
static makeVideoObject(ob){
|
|
const codec_id = ("codec_id" in ob && ob.codec_id.match(/^[0-9]+$/) === null) ? ob.codec_id : ("codec_id_hint" in ob ? ob.codec_id_hint : ob.format);
|
|
|
|
ob.codec_id = codec_id;
|
|
|
|
ob.__videoCodec = Mediainfo.matchCodec(Mediainfo.videoCodecs, ob, {
|
|
name: codec_id
|
|
});
|
|
}
|
|
|
|
static makeAudioObject(ob){
|
|
const channels = parseInt(("channels" in ob ? ob.channels : ("channel_count" in ob ? ob.channel_count : "1 channel")).match(/(?<channels>[0-9]+) channels?[\s]*(\/|$)/).groups.channels);
|
|
const codec_id = ("codec_id" in ob && ob.codec_id.match(/^[0-9]+$/) === null) ? ob.codec_id : ("codec_id_hint" in ob ? ob.codec_id_hint : ob.format);
|
|
|
|
ob.channels = channels;
|
|
|
|
ob.codec_id = codec_id;
|
|
|
|
ob.__audioCodec = Mediainfo.matchCodec(Mediainfo.audioCodecs, ob, {
|
|
name: codec_id
|
|
});
|
|
}
|
|
|
|
static matchCodec(codecs, ob, fallback = null){
|
|
let matchObject = fallback;
|
|
codecs.every((codec) => {
|
|
let match = true;
|
|
let n = codec.name;
|
|
let l = codec.legacy;
|
|
let m = null;
|
|
for(const [key, value] of Object.entries(codec.match)){
|
|
if(value === null){
|
|
if(key in ob){
|
|
match = false;
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
if(!(key in ob)){
|
|
match = false;
|
|
break;
|
|
}else if (value instanceof RegExp){
|
|
if((m = ob[key].match(value)) === null){
|
|
match = false;
|
|
break;
|
|
}
|
|
|
|
if("groups" in m && typeof m.groups === "object"){
|
|
for(const [k, v] of Object.entries(m.groups)){
|
|
if(typeof v !== "undefined"){
|
|
n = n.replace('$' + k, v);
|
|
l = l.replace('$' + k, v);
|
|
}else{
|
|
n = n.replace('$' + k, "");
|
|
l = l.replace('$' + k, "");
|
|
}
|
|
}
|
|
}
|
|
}else if (!(value instanceof RegExp) && ob[key] !== value){
|
|
match = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(match){
|
|
matchObject = Object.assign({}, codec);
|
|
matchObject.name = n.trim();
|
|
matchObject.legacy = l.trim();
|
|
}
|
|
|
|
return !match;
|
|
});
|
|
|
|
return matchObject;
|
|
}
|
|
|
|
static getAudioChannels(a){
|
|
if(a === 3){
|
|
return "2.1";
|
|
}else if(a === 5){
|
|
return "4.1";
|
|
}else if(a === 6){
|
|
return "5.1";
|
|
}else if(a === 7){
|
|
return "6.1";
|
|
}else if(a === 8){
|
|
return "7.1";
|
|
}
|
|
|
|
return a + ".0";
|
|
}
|
|
|
|
static parseText(text) {
|
|
let ob = {};
|
|
let currentKey = null;
|
|
let currentOb = null;
|
|
|
|
try{
|
|
text.split("\n").forEach((line) => {
|
|
const cleanLine = line.trim();
|
|
if(cleanLine === ""){
|
|
return;
|
|
}else if(!cleanLine.includes(":")){
|
|
if(currentOb !== null && Object.keys(currentOb).length === 0){
|
|
//Nothing added, error, invalid mediainfo
|
|
throw ("Invalid key " + currentKey);
|
|
}
|
|
if(currentKey === null && cleanLine.toLowerCase() !== "general"){
|
|
throw ("Invalid first key " + cleanLine.toLowerCase());
|
|
}else if (currentKey !== null && cleanLine.toLowerCase() === "general"){
|
|
throw ("Found another general entry");
|
|
}
|
|
currentKey = cleanLine.toLowerCase();
|
|
let listMatch = currentKey.match(/^(?<kind>(video|audio|text))( #)?(?<number>[0-9]*)$/i);
|
|
currentOb = {};
|
|
if(listMatch !== null){
|
|
let k = listMatch.groups.kind;
|
|
if(!(k in ob)){
|
|
ob[k] = [];
|
|
}
|
|
ob[k].push(currentOb);
|
|
}else{
|
|
ob[currentKey] = currentOb;
|
|
}
|
|
}else if(currentOb !== null){
|
|
const matches = currentKey === "menu" ? cleanLine.match(/^(?<key>([0-9]+:)+[0-9]+(\.[0-9]+)?)[\s]*:(?<value>.+)$/) : cleanLine.match(/^(?<key>((?!\s?:).)+)[\s]*:(?<value>.+)$/);
|
|
if(matches !== null){
|
|
let key = matches.groups.key.trim().toLowerCase().replace(/[ \/*]/g, "_").replace(/[(),]/g, "");
|
|
currentOb[key] = matches.groups.value.trim();
|
|
}else{
|
|
throw "Invalid entry: " + cleanLine;
|
|
}
|
|
}else{
|
|
throw "Invalid state: " + cleanLine;
|
|
}
|
|
});
|
|
}catch (e){
|
|
console.log(text);
|
|
console.log(e);
|
|
if("general" in ob && "video" in ob){ //Return whatever we have
|
|
return ob;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
return ob;
|
|
}
|
|
} |