Пример #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NamingOptions"/> class.
        /// </summary>
        public NamingOptions()
        {
            VideoFileExtensions = new[]
            {
                ".001",
                ".3g2",
                ".3gp",
                ".amv",
                ".asf",
                ".asx",
                ".avi",
                ".bin",
                ".bivx",
                ".divx",
                ".dv",
                ".dvr-ms",
                ".f4v",
                ".fli",
                ".flv",
                ".ifo",
                ".img",
                ".iso",
                ".m2t",
                ".m2ts",
                ".m2v",
                ".m4v",
                ".mkv",
                ".mk3d",
                ".mov",
                ".mp2",
                ".mp4",
                ".mpe",
                ".mpeg",
                ".mpg",
                ".mts",
                ".mxf",
                ".nrg",
                ".nsv",
                ".nuv",
                ".ogg",
                ".ogm",
                ".ogv",
                ".pva",
                ".qt",
                ".rec",
                ".rm",
                ".rmvb",
                ".svq3",
                ".tp",
                ".ts",
                ".ty",
                ".viv",
                ".vob",
                ".vp3",
                ".webm",
                ".wmv",
                ".wtv",
                ".xvid"
            };

            VideoFlagDelimiters = new[]
            {
                '(',
                ')',
                '-',
                '.',
                '_',
                '[',
                ']'
            };

            StubFileExtensions = new[]
            {
                ".disc"
            };

            StubTypes = new[]
            {
                new StubTypeRule(
                    stubType: "dvd",
                    token: "dvd"),

                new StubTypeRule(
                    stubType: "hddvd",
                    token: "hddvd"),

                new StubTypeRule(
                    stubType: "bluray",
                    token: "bluray"),

                new StubTypeRule(
                    stubType: "bluray",
                    token: "brrip"),

                new StubTypeRule(
                    stubType: "bluray",
                    token: "bd25"),

                new StubTypeRule(
                    stubType: "bluray",
                    token: "bd50"),

                new StubTypeRule(
                    stubType: "vhs",
                    token: "vhs"),

                new StubTypeRule(
                    stubType: "tv",
                    token: "HDTV"),

                new StubTypeRule(
                    stubType: "tv",
                    token: "PDTV"),

                new StubTypeRule(
                    stubType: "tv",
                    token: "DSR")
            };

            VideoFileStackingRules = new[]
            {
                new FileStackRule(@"^(?<filename>.*?)(?:(?<=[\]\)\}])|[ _.-]+)[\(\[]?(?<parttype>cd|dvd|part|pt|dis[ck])[ _.-]*(?<number>[0-9]+)[\)\]]?(?:\.[^.]+)?$", true),
                new FileStackRule(@"^(?<filename>.*?)(?:(?<=[\]\)\}])|[ _.-]+)[\(\[]?(?<parttype>cd|dvd|part|pt|dis[ck])[ _.-]*(?<number>[a-d])[\)\]]?(?:\.[^.]+)?$", false),
                new FileStackRule(@"^(?<filename>.*?)(?:(?<=[\]\)\}])|[ _.-]?)(?<number>[a-d])(?:\.[^.]+)?$", false)
            };

            CleanDateTimes = new[]
            {
                @"(.+[^_\,\.\(\)\[\]\-])[_\.\(\)\[\]\-](19[0-9]{2}|20[0-9]{2})(?![0-9]+|\W[0-9]{2}\W[0-9]{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19[0-9]{2}|20[0-9]{2})*",
                @"(.+[^_\,\.\(\)\[\]\-])[ _\.\(\)\[\]\-]+(19[0-9]{2}|20[0-9]{2})(?![0-9]+|\W[0-9]{2}\W[0-9]{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19[0-9]{2}|20[0-9]{2})*"
            };

            CleanStrings = new[]
            {
                @"^\s*(?<cleaned>.+?)[ _\,\.\(\)\[\]\-](3d|sbs|tab|hsbs|htab|mvc|HDR|HDC|UHD|UltraHD|4k|ac3|dts|custom|dc|divx|divx5|dsr|dsrip|dutch|dvd|dvdrip|dvdscr|dvdscreener|screener|dvdivx|cam|fragment|fs|hdtv|hdrip|hdtvrip|internal|limited|multisubs|ntsc|ogg|ogm|pal|pdtv|proper|repack|rerip|retail|cd[1-9]|r3|r5|bd5|bd|se|svcd|swedish|german|read.nfo|nfofix|unrated|ws|telesync|ts|telecine|tc|brrip|bdrip|480p|480i|576p|576i|720p|720i|1080p|1080i|2160p|hrhd|hrhdtv|hddvd|bluray|blu-ray|x264|x265|h264|h265|xvid|xvidvd|xxx|www.www|AAC|DTS|\[.*\])([ _\,\.\(\)\[\]\-]|$)",
                @"^(?<cleaned>.+?)(\[.*\])",
                @"^\s*(?<cleaned>.+?)\WE[0-9]+(-|~)E?[0-9]+(\W|$)",
                @"^\s*\[[^\]]+\](?!\.\w+$)\s*(?<cleaned>.+)",
                @"^\s*(?<cleaned>.+?)\s+-\s+[0-9]+\s*$"
            };

            SubtitleFileExtensions = new[]
            {
                ".ass",
                ".mks",
                ".sami",
                ".smi",
                ".srt",
                ".ssa",
                ".sub",
                ".vtt",
            };

            AlbumStackingPrefixes = new[]
            {
                "cd",
                "disc",
                "disk",
                "vol",
                "volume"
            };

            AudioFileExtensions = new[]
            {
                ".669",
                ".3gp",
                ".aa",
                ".aac",
                ".aax",
                ".ac3",
                ".act",
                ".adp",
                ".adplug",
                ".adx",
                ".afc",
                ".amf",
                ".aif",
                ".aiff",
                ".alac",
                ".amr",
                ".ape",
                ".ast",
                ".au",
                ".awb",
                ".cda",
                ".cue",
                ".dmf",
                ".dsf",
                ".dsm",
                ".dsp",
                ".dts",
                ".dvf",
                ".far",
                ".flac",
                ".gdm",
                ".gsm",
                ".gym",
                ".hps",
                ".imf",
                ".it",
                ".m15",
                ".m4a",
                ".m4b",
                ".mac",
                ".med",
                ".mka",
                ".mmf",
                ".mod",
                ".mogg",
                ".mp2",
                ".mp3",
                ".mpa",
                ".mpc",
                ".mpp",
                ".mp+",
                ".msv",
                ".nmf",
                ".nsf",
                ".nsv",
                ".oga",
                ".ogg",
                ".okt",
                ".opus",
                ".pls",
                ".ra",
                ".rf64",
                ".rm",
                ".s3m",
                ".sfx",
                ".shn",
                ".sid",
                ".spc",
                ".stm",
                ".strm",
                ".ult",
                ".uni",
                ".vox",
                ".wav",
                ".wma",
                ".wv",
                ".xm",
                ".xsp",
                ".ymf"
            };

            MediaFlagDelimiters = new[]
            {
                "."
            };

            MediaForcedFlags = new[]
            {
                "foreign",
                "forced"
            };

            MediaDefaultFlags = new[]
            {
                "default"
            };

            EpisodeExpressions = new[]
            {
                // *** Begin Kodi Standard Naming
                // <!-- foo.s01.e01, foo.s01_e01, S01E02 foo, S01 - E02 -->
                new EpisodeExpression(@".*(\\|\/)(?<seriesname>((?![Ss]([0-9]+)[][ ._-]*[Ee]([0-9]+))[^\\\/])*)?[Ss](?<seasonnumber>[0-9]+)[][ ._-]*[Ee](?<epnumber>[0-9]+)([^\\/]*)$")
                {
                    IsNamed = true
                },
                // <!-- foo.ep01, foo.EP_01 -->
                new EpisodeExpression(@"[\._ -]()[Ee][Pp]_?([0-9]+)([^\\/]*)$"),
                // <!-- foo.E01., foo.e01. -->
                new EpisodeExpression(@"[^\\/]*?()\.?[Ee]([0-9]+)\.([^\\/]*)$"),
                new EpisodeExpression("(?<year>[0-9]{4})[\\.-](?<month>[0-9]{2})[\\.-](?<day>[0-9]{2})", true)
                {
                    DateTimeFormats = new[]
                    {
                        "yyyy.MM.dd",
                        "yyyy-MM-dd",
                        "yyyy_MM_dd"
                    }
                },
                new EpisodeExpression(@"(?<day>[0-9]{2})[.-](?<month>[0-9]{2})[.-](?<year>[0-9]{4})", true)
                {
                    DateTimeFormats = new[]
                    {
                        "dd.MM.yyyy",
                        "dd-MM-yyyy",
                        "dd_MM_yyyy"
                    }
                },

                // This isn't a Kodi naming rule, but the expression below causes false positives,
                // so we make sure this one gets tested first.
                // "Foo Bar 889"
                new EpisodeExpression(@".*[\\\/](?![Ee]pisode)(?<seriesname>[\w\s]+?)\s(?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*[^\\\/x]*$")
                {
                    IsNamed = true
                },

                new EpisodeExpression(@"[\\\/\._ \[\(-]([0-9]+)x([0-9]+(?:(?:[a-i]|\.[1-9])(?![0-9]))?)([^\\\/]*)$")
                {
                    SupportsAbsoluteEpisodeNumbers = true
                },

                // Not a Kodi rule as well, but below rule also causes false positives for triple-digit episode names
                // [bar] Foo - 1 [baz] special case of below expression to prevent false positives with digits in the series name
                new EpisodeExpression(@".*[\\\/]?.*?(\[.*?\])+.*?(?<seriesname>[-\w\s]+?)[\s_]*-[\s_]*(?<epnumber>[0-9]+).*$")
                {
                    IsNamed = true
                },

                // /server/anything_102.mp4
                // /server/james.corden.2017.04.20.anne.hathaway.720p.hdtv.x264-crooks.mkv
                // /server/anything_1996.11.14.mp4
                new EpisodeExpression(@"[\\/._ -](?<seriesname>(?![0-9]+[0-9][0-9])([^\\\/_])*)[\\\/._ -](?<seasonnumber>[0-9]+)(?<epnumber>[0-9][0-9](?:(?:[a-i]|\.[1-9])(?![0-9]))?)([._ -][^\\\/]*)$")
                {
                    IsOptimistic = true,
                    IsNamed      = true,
                    SupportsAbsoluteEpisodeNumbers = false
                },
                new EpisodeExpression("[\\/._ -]p(?:ar)?t[_. -]()([ivx]+|[0-9]+)([._ -][^\\/]*)$")
                {
                    SupportsAbsoluteEpisodeNumbers = true
                },

                // *** End Kodi Standard Naming

                // "Episode 16", "Episode 16 - Title"
                new EpisodeExpression(@"[Ee]pisode (?<epnumber>[0-9]+)(-(?<endingepnumber>[0-9]+))?[^\\\/]*$")
                {
                    IsNamed = true
                },

                new EpisodeExpression(@".*(\\|\/)[sS]?(?<seasonnumber>[0-9]+)[xX](?<epnumber>[0-9]+)[^\\\/]*$")
                {
                    IsNamed = true
                },

                new EpisodeExpression(@".*(\\|\/)[sS](?<seasonnumber>[0-9]+)[x,X]?[eE](?<epnumber>[0-9]+)[^\\\/]*$")
                {
                    IsNamed = true
                },

                new EpisodeExpression(@".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]+))[^\\\/]*$")
                {
                    IsNamed = true
                },

                new EpisodeExpression(@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>[0-9]{1,4})[xX\.]?[eE](?<epnumber>[0-9]+)[^\\\/]*$")
                {
                    IsNamed = true
                },

                // "01.avi"
                new EpisodeExpression(@".*[\\\/](?<epnumber>[0-9]+)(-(?<endingepnumber>[0-9]+))*\.\w+$")
                {
                    IsOptimistic = true,
                    IsNamed      = true
                },

                // "1-12 episode title"
                new EpisodeExpression(@"([0-9]+)-([0-9]+)"),

                // "01 - blah.avi", "01-blah.avi"
                new EpisodeExpression(@".*(\\|\/)(?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*\s?-\s?[^\\\/]*$")
                {
                    IsOptimistic = true,
                    IsNamed      = true
                },

                // "01.blah.avi"
                new EpisodeExpression(@".*(\\|\/)(?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*\.[^\\\/]+$")
                {
                    IsOptimistic = true,
                    IsNamed      = true
                },

                // "blah - 01.avi", "blah 2 - 01.avi", "blah - 01 blah.avi", "blah 2 - 01 blah", "blah - 01 - blah.avi", "blah 2 - 01 - blah"
                new EpisodeExpression(@".*[\\\/][^\\\/]* - (?<epnumber>[0-9]{1,3})(-(?<endingepnumber>[0-9]{2,3}))*[^\\\/]*$")
                {
                    IsOptimistic = true,
                    IsNamed      = true
                },

                // "01 episode title.avi"
                new EpisodeExpression(@"[Ss]eason[\._ ](?<seasonnumber>[0-9]+)[\\\/](?<epnumber>[0-9]{1,3})([^\\\/]*)$")
                {
                    IsOptimistic = true,
                    IsNamed      = true
                },

                // Series and season only expression
                // "the show/season 1", "the show/s01"
                new EpisodeExpression(@"(.*(\\|\/))*(?<seriesname>.+)\/[Ss](eason)?[\. _\-]*(?<seasonnumber>[0-9]+)")
                {
                    IsNamed = true
                },

                // Series and season only expression
                // "the show S01", "the show season 1"
                new EpisodeExpression(@"(.*(\\|\/))*(?<seriesname>.+)[\. _\-]+[sS](eason)?[\. _\-]*(?<seasonnumber>[0-9]+)")
                {
                    IsNamed = true
                },
            };

            EpisodeWithoutSeasonExpressions = new[]
            {
                @"[/\._ \-]()([0-9]+)(-[0-9]+)?"
            };

            EpisodeMultiPartExpressions = new[]
            {
                @"^[-_ex]+([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)"
            };

            VideoExtraRules = new[]
            {
                new ExtraRule(
                    ExtraType.Trailer,
                    ExtraRuleType.DirectoryName,
                    "trailers",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.ThemeVideo,
                    ExtraRuleType.DirectoryName,
                    "backdrops",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.ThemeSong,
                    ExtraRuleType.DirectoryName,
                    "theme-music",
                    MediaType.Audio),

                new ExtraRule(
                    ExtraType.BehindTheScenes,
                    ExtraRuleType.DirectoryName,
                    "behind the scenes",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.DeletedScene,
                    ExtraRuleType.DirectoryName,
                    "deleted scenes",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Interview,
                    ExtraRuleType.DirectoryName,
                    "interviews",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Scene,
                    ExtraRuleType.DirectoryName,
                    "scenes",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Sample,
                    ExtraRuleType.DirectoryName,
                    "samples",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Clip,
                    ExtraRuleType.DirectoryName,
                    "shorts",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Clip,
                    ExtraRuleType.DirectoryName,
                    "featurettes",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Unknown,
                    ExtraRuleType.DirectoryName,
                    "extras",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Trailer,
                    ExtraRuleType.Filename,
                    "trailer",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Trailer,
                    ExtraRuleType.Suffix,
                    "-trailer",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Trailer,
                    ExtraRuleType.Suffix,
                    ".trailer",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Trailer,
                    ExtraRuleType.Suffix,
                    "_trailer",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Trailer,
                    ExtraRuleType.Suffix,
                    " trailer",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Sample,
                    ExtraRuleType.Filename,
                    "sample",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Sample,
                    ExtraRuleType.Suffix,
                    "-sample",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Sample,
                    ExtraRuleType.Suffix,
                    ".sample",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Sample,
                    ExtraRuleType.Suffix,
                    "_sample",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Sample,
                    ExtraRuleType.Suffix,
                    " sample",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.ThemeSong,
                    ExtraRuleType.Filename,
                    "theme",
                    MediaType.Audio),

                new ExtraRule(
                    ExtraType.Scene,
                    ExtraRuleType.Suffix,
                    "-scene",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Clip,
                    ExtraRuleType.Suffix,
                    "-clip",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Interview,
                    ExtraRuleType.Suffix,
                    "-interview",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.BehindTheScenes,
                    ExtraRuleType.Suffix,
                    "-behindthescenes",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.DeletedScene,
                    ExtraRuleType.Suffix,
                    "-deleted",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.DeletedScene,
                    ExtraRuleType.Suffix,
                    "-deletedscene",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Clip,
                    ExtraRuleType.Suffix,
                    "-featurette",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Clip,
                    ExtraRuleType.Suffix,
                    "-short",
                    MediaType.Video),

                new ExtraRule(
                    ExtraType.Unknown,
                    ExtraRuleType.Suffix,
                    "-extra",
                    MediaType.Video)
            };

            AllExtrasTypesFolderNames = VideoExtraRules
                                        .Where(i => i.RuleType == ExtraRuleType.DirectoryName)
                                        .ToDictionary(i => i.Token, i => i.ExtraType, StringComparer.OrdinalIgnoreCase);

            Format3DRules = new[]
            {
                // Kodi rules:
                new Format3DRule(
                    precedingToken: "3d",
                    token: "hsbs"),

                new Format3DRule(
                    precedingToken: "3d",
                    token: "sbs"),

                new Format3DRule(
                    precedingToken: "3d",
                    token: "htab"),

                new Format3DRule(
                    precedingToken: "3d",
                    token: "tab"),

                // Media Browser rules:
                new Format3DRule("fsbs"),
                new Format3DRule("hsbs"),
                new Format3DRule("sbs"),
                new Format3DRule("ftab"),
                new Format3DRule("htab"),
                new Format3DRule("tab"),
                new Format3DRule("sbs3d"),
                new Format3DRule("mvc")
            };

            AudioBookPartsExpressions = new[]
            {
                // Detect specified chapters, like CH 01
                @"ch(?:apter)?[\s_-]?(?<chapter>[0-9]+)",
                // Detect specified parts, like Part 02
                @"p(?:ar)?t[\s_-]?(?<part>[0-9]+)",
                // Chapter is often beginning of filename
                "^(?<chapter>[0-9]+)",
                // Part if often ending of filename
                @"(?<!ch(?:apter) )(?<part>[0-9]+)$",
                // Sometimes named as 0001_005 (chapter_part)
                "(?<chapter>[0-9]+)_(?<part>[0-9]+)",
                // Some audiobooks are ripped from cd's, and will be named by disk number.
                @"dis(?:c|k)[\s_-]?(?<chapter>[0-9]+)"
            };

            AudioBookNamesExpressions = new[]
            {
                // Detect year usually in brackets after name Batman (2020)
                @"^(?<name>.+?)\s*\(\s*(?<year>[0-9]{4})\s*\)\s*$",
                @"^\s*(?<name>[^ ].*?)\s*$"
            };

            MultipleEpisodeExpressions = new[]
            {
                @".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})((-| - )[0-9]{1,4}[eExX](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
                @".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})((-| - )[0-9]{1,4}[xX][eE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
                @".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})((-| - )?[xXeE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
                @".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})(-[xE]?[eE]?(?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
                @".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3}))((-| - )[0-9]{1,4}[xXeE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
                @".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3}))((-| - )[0-9]{1,4}[xX][eE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
                @".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3}))((-| - )?[xXeE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
                @".*(\\|\/)(?<seriesname>((?![sS]?[0-9]{1,4}[xX][0-9]{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3}))(-[xX]?[eE]?(?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
                @".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>[0-9]{1,4})[xX\.]?[eE](?<epnumber>[0-9]{1,3})((-| - )?[xXeE](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
                @".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>[0-9]{1,4})[xX\.]?[eE](?<epnumber>[0-9]{1,3})(-[xX]?[eE]?(?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$"
            }.Select(i => new EpisodeExpression(i)
            {
                IsNamed = true
            }).ToArray();

            Compile();
        }
Пример #2
0
        public ExtendedNamingOptions()
        {
            var extensions = VideoFileExtensions.ToList();

            extensions.AddRange(new[]
            {
                ".mkv",
                ".m2t",
                ".m2ts",
                ".img",
                ".iso",
                ".mk3d",
                ".ts",
                ".rmvb",
                ".mov",
                ".avi",
                ".mpg",
                ".mpeg",
                ".wmv",
                ".mp4",
                ".divx",
                ".dvr-ms",
                ".wtv",
                ".ogm",
                ".ogv",
                ".asf",
                ".m4v",
                ".flv",
                ".f4v",
                ".3gp",
                ".webm",
                ".mts",
                ".m2v",
                ".rec"
            });

            // Problematic. Can always become configurable if needed.
            extensions.Remove(".dat");
            extensions.Remove(".wpl");
            extensions.Remove(".m3u");

            VideoFileExtensions = extensions
                                  .Distinct(StringComparer.OrdinalIgnoreCase)
                                  .ToList();

            VideoExtraRules.AddRange(new List <ExtraRule>
            {
                new ExtraRule
                {
                    ExtraType = "scene",
                    RuleType  = ExtraRuleType.Suffix,
                    Token     = "-scene",
                    MediaType = MediaType.Video
                },
                new ExtraRule
                {
                    ExtraType = "clip",
                    RuleType  = ExtraRuleType.Suffix,
                    Token     = "-clip",
                    MediaType = MediaType.Video
                },
                new ExtraRule
                {
                    ExtraType = "interview",
                    RuleType  = ExtraRuleType.Suffix,
                    Token     = "-interview",
                    MediaType = MediaType.Video
                },
                new ExtraRule
                {
                    ExtraType = "behindthescenes",
                    RuleType  = ExtraRuleType.Suffix,
                    Token     = "-behindthescenes",
                    MediaType = MediaType.Video
                },
                new ExtraRule
                {
                    ExtraType = "deletedscene",
                    RuleType  = ExtraRuleType.Suffix,
                    Token     = "-deleted",
                    MediaType = MediaType.Video
                }
            });

            Format3DRules.AddRange(new List <Format3DRule>
            {
                // Media Browser rules:
                new Format3DRule
                {
                    Token = "fsbs"
                },
                new Format3DRule
                {
                    Token = "hsbs"
                },
                new Format3DRule
                {
                    Token = "sbs"
                },
                new Format3DRule
                {
                    Token = "ftab"
                },
                new Format3DRule
                {
                    Token = "htab"
                },
                new Format3DRule
                {
                    Token = "tab"
                },
                new Format3DRule
                {
                    Token = "sbs3d"
                },
                new Format3DRule
                {
                    Token = "mvc"
                }
            });
        }