Example #1
0
        public static string FormatVideoDynamicRangeType(MediaInfoModel mediaInfo)
        {
            switch (mediaInfo.GetHdrFormat())
            {
            case HdrFormat.DolbyVision:
                return("DV");

            case HdrFormat.DolbyVisionHdr10:
                return("DV HDR10");

            case HdrFormat.Hdr10:
                return("HDR10");

            case HdrFormat.Hdr10Plus:
                return("HDR10Plus");

            case HdrFormat.Hlg10:
                return("HLG");

            case HdrFormat.Pq10:
                return("PQ");

            case HdrFormat.UnknownHdr:
                return("HDR");
            }

            return("");
        }
Example #2
0
        public static string FormatVideoCodec(MediaInfoModel mediaInfo, string sceneName)
        {
            var videoCodec = mediaInfo.VideoCodec;

            if (videoCodec == "AVC")
            {
                return(sceneName.IsNotNullOrWhiteSpace() && Path.GetFileNameWithoutExtension(sceneName).Contains("h264")
                    ? "h264"
                    : "x264");
            }

            if (videoCodec == "V_MPEGH/ISO/HEVC")
            {
                return(sceneName.IsNotNullOrWhiteSpace() && Path.GetFileNameWithoutExtension(sceneName).Contains("h265")
                    ? "h265"
                    : "x265");
            }

            if (videoCodec == "MPEG-2 Video")
            {
                return("MPEG2");
            }

            Logger.Error("Unknown video codec: {0}", videoCodec);
            return(videoCodec);
        }
Example #3
0
        private static decimal?FormatAudioChannelsFromAudioChannels(MediaInfoModel mediaInfo)
        {
            var audioChannelsContainer = mediaInfo.AudioChannelsContainer;
            var audioChannelsStream    = mediaInfo.AudioChannelsStream;

            var audioFormat             = (mediaInfo.AudioFormat ?? string.Empty).Trim().Split(new[] { " / " }, StringSplitOptions.RemoveEmptyEntries);
            var splitAdditionalFeatures = (mediaInfo.AudioAdditionalFeatures ?? string.Empty).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            // Workaround https://github.com/MediaArea/MediaInfo/issues/299 for DTS-X Audio
            if (audioFormat.ContainsIgnoreCase("DTS") &&
                splitAdditionalFeatures.ContainsIgnoreCase("XLL") &&
                splitAdditionalFeatures.ContainsIgnoreCase("X") &&
                audioChannelsContainer > 0)
            {
                return(audioChannelsContainer - 1 + 0.1m);
            }

            // FLAC 6 channels is likely 5.1
            if (audioFormat.ContainsIgnoreCase("FLAC") && audioChannelsContainer == 6)
            {
                return(5.1m);
            }

            if (mediaInfo.SchemaRevision > 5)
            {
                return(audioChannelsStream > 0 ? audioChannelsStream : audioChannelsContainer);
            }

            if (mediaInfo.SchemaRevision >= 3)
            {
                return(audioChannelsContainer);
            }

            return(null);
        }
Example #4
0
        private static decimal?FormatAudioChannelsFromAudioChannelPositions(MediaInfoModel mediaInfo)
        {
            var audioChannelPositions = mediaInfo.AudioChannelPositions;

            if (audioChannelPositions.IsNullOrWhiteSpace())
            {
                return(null);
            }

            try
            {
                Logger.Debug("Formatiting audio channels using 'AudioChannelPositions', with a value of: '{0}'", audioChannelPositions);

                if (audioChannelPositions.Contains("+"))
                {
                    return(audioChannelPositions.Split('+')
                           .Sum(s => decimal.Parse(s.Trim(), CultureInfo.InvariantCulture)));
                }


                return(Regex.Replace(audioChannelPositions, @"^\d+\sobjects", "", RegexOptions.Compiled | RegexOptions.IgnoreCase)
                       .Replace("Object Based / ", "")
                       .Split(new string[] { " / " }, StringSplitOptions.RemoveEmptyEntries)
                       .FirstOrDefault()
                       ?.Split('/')
                       .Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture)));
            }
            catch (Exception e)
            {
                Logger.Warn(e, "Unable to format audio channels using 'AudioChannelPositions'");
            }

            return(null);
        }
Example #5
0
        public static decimal FormatAudioChannels(MediaInfoModel mediaInfo)
        {
            var audioChannelPositions     = mediaInfo.AudioChannelPositions;
            var audioChannelPositionsText = mediaInfo.AudioChannelPositionsText;
            var audioChannels             = mediaInfo.AudioChannels;

            if (audioChannelPositions.IsNullOrWhiteSpace())
            {
                if (audioChannelPositionsText.IsNullOrWhiteSpace())
                {
                    if (mediaInfo.SchemaRevision >= 3)
                    {
                        return(audioChannels);
                    }

                    return(0);
                }

                return(mediaInfo.AudioChannelPositionsText.ContainsIgnoreCase("LFE") ? audioChannels - 1 + 0.1m : audioChannels);
            }

            return(audioChannelPositions.Replace("Object Based / ", "")
                   .Split(new string[] { " / " }, StringSplitOptions.None)
                   .First()
                   .Split('/')
                   .Sum(s => decimal.Parse(s, CultureInfo.InvariantCulture)));
        }
Example #6
0
        public static string FormatAudioCodec(MediaInfoModel mediaInfo)
        {
            var audioFormat = mediaInfo.AudioFormat;

            if (audioFormat == "AC-3")
            {
                return("AC3");
            }

            if (audioFormat == "E-AC-3")
            {
                return("EAC3");
            }

            if (audioFormat == "AAC")
            {
                return("AAC");
            }

            if (audioFormat == "MPEG Audio")
            {
                return(mediaInfo.AudioProfile == "Layer 3" ? "MP3" : audioFormat);
            }

            if (audioFormat == "DTS")
            {
                return("DTS");
            }

            Logger.Error("Unknown audio format: {0}", audioFormat);
            return(audioFormat);
        }
Example #7
0
        private static decimal?FormatAudioChannelsFromAudioChannelPositionsText(MediaInfoModel mediaInfo)
        {
            var audioChannelPositionsTextContainer = mediaInfo.AudioChannelPositionsTextContainer;
            var audioChannelPositionsTextStream    = mediaInfo.AudioChannelPositionsTextStream;
            var audioChannelsContainer             = mediaInfo.AudioChannelsContainer;
            var audioChannelsStream = mediaInfo.AudioChannelsStream;

            //Skip if the positions texts give us nothing
            if ((audioChannelPositionsTextContainer.IsNullOrWhiteSpace() || audioChannelPositionsTextContainer == "Object Based") &&
                (audioChannelPositionsTextStream.IsNullOrWhiteSpace() || audioChannelPositionsTextStream == "Object Based"))
            {
                return(null);
            }

            try
            {
                if (audioChannelsStream > 0)
                {
                    return(audioChannelPositionsTextStream.ContainsIgnoreCase("LFE") ? audioChannelsStream - 1 + 0.1m : audioChannelsStream);
                }

                return(audioChannelPositionsTextContainer.ContainsIgnoreCase("LFE") ? audioChannelsContainer - 1 + 0.1m : audioChannelsContainer);
            }
            catch (Exception e)
            {
                Logger.Warn(e, "Unable to format audio channels using 'AudioChannelPositionsText' or 'AudioChannelPositionsTextStream', with value of: '{0}' and '{1}", audioChannelPositionsTextContainer, audioChannelPositionsTextStream);
            }

            return(null);
        }
Example #8
0
        public static string FormatAudioCodecLegacy(MediaInfoModel mediaInfo, string sceneName)
        {
            var audioFormat = mediaInfo.AudioFormat;

            if (audioFormat.IsNullOrWhiteSpace())
            {
                return(audioFormat);
            }

            if (audioFormat.EqualsIgnoreCase("AC-3"))
            {
                return("AC3");
            }

            if (audioFormat.EqualsIgnoreCase("E-AC-3"))
            {
                return("EAC3");
            }

            if (audioFormat.EqualsIgnoreCase("AAC"))
            {
                return("AAC");
            }

            if (audioFormat.EqualsIgnoreCase("MPEG Audio") && mediaInfo.AudioProfile == "Layer 3")
            {
                return("MP3");
            }

            if (audioFormat.EqualsIgnoreCase("DTS"))
            {
                return("DTS");
            }

            if (audioFormat.EqualsIgnoreCase("TrueHD"))
            {
                return("TrueHD");
            }

            if (audioFormat.EqualsIgnoreCase("FLAC"))
            {
                return("FLAC");
            }

            if (audioFormat.EqualsIgnoreCase("Vorbis"))
            {
                return("Vorbis");
            }

            if (audioFormat.EqualsIgnoreCase("Opus"))
            {
                return("Opus");
            }

            return(audioFormat);
        }
        public static HdrFormat GetHdrFormat(this MediaInfoModel mediaInfo)
        {
            if (mediaInfo.VideoBitDepth < 10)
            {
                return(HdrFormat.None);
            }

            if (mediaInfo.VideoHdrFormat.IsNotNullOrWhiteSpace())
            {
                if (DolbyVisionFormats.Any(mediaInfo.VideoHdrFormat.ContainsIgnoreCase))
                {
                    if (Hdr10Formats.Any(mediaInfo.VideoHdrFormat.ContainsIgnoreCase))
                    {
                        return(HdrFormat.DolbyVisionHdr10);
                    }
                    else
                    {
                        return(HdrFormat.DolbyVision);
                    }
                }
                else if (Hdr10Formats.Any(mediaInfo.VideoHdrFormat.ContainsIgnoreCase))
                {
                    return(HdrFormat.Hdr10);
                }
                else if (Hdr10PlusFormats.Any(mediaInfo.VideoHdrFormat.ContainsIgnoreCase))
                {
                    return(HdrFormat.Hdr10Plus);
                }
            }

            //
            // We didn't match straight from the format from MediaInfo, so try and match in ColourPrimaries and TransferCharacteristics
            //
            if (mediaInfo.VideoColourPrimaries.IsNotNullOrWhiteSpace() && mediaInfo.VideoTransferCharacteristics.IsNotNullOrWhiteSpace())
            {
                if (mediaInfo.VideoColourPrimaries.EqualsIgnoreCase(ValidHdrColourPrimaries))
                {
                    if (mediaInfo.VideoTransferCharacteristics.EqualsIgnoreCase(PgTransferFunction))
                    {
                        return(HdrFormat.Pq10);
                    }
                    else if (mediaInfo.VideoTransferCharacteristics.EqualsIgnoreCase(HlgTransferFunction))
                    {
                        return(HdrFormat.Hlg10);
                    }
                }
            }

            if (mediaInfo.VideoHdrFormat.IsNotNullOrWhiteSpace())
            {
                return(HdrFormat.UnknownHdr); // MediaInfo reported Hdr information, but we're unsure of what type.
            }

            return(HdrFormat.None);
        }
Example #10
0
        private static decimal?FormatAudioChannelsFromAudioChannels(MediaInfoModel mediaInfo)
        {
            var audioChannels = mediaInfo.AudioChannels;

            if (mediaInfo.SchemaRevision >= 3)
            {
                return(audioChannels);
            }

            return(null);
        }
Example #11
0
        public static decimal FormatAudioChannels(MediaInfoModel mediaInfo)
        {
            var audioChannels = FormatAudioChannelsFromAudioChannelPositions(mediaInfo);

            if (audioChannels == null || audioChannels == 0.0m)
            {
                audioChannels = mediaInfo.AudioChannels;
            }

            return(audioChannels.Value);
        }
Example #12
0
        private static decimal?FormatAudioChannelsFromAudioChannels(MediaInfoModel mediaInfo)
        {
            var audioChannels = mediaInfo.AudioChannels;

            if (mediaInfo.SchemaRevision >= 3)
            {
                Logger.Debug("Formatting audio channels using 'AudioChannels', with a value of: '{0}'", audioChannels);

                return(audioChannels);
            }

            return(null);
        }
Example #13
0
        public static decimal FormatAudioChannels(MediaInfoModel mediaInfo)
        {
            var audioChannels = FormatAudioChannelsFromAudioChannelPositions(mediaInfo);

            if (audioChannels == null)
            {
                audioChannels = FormatAudioChannelsFromAudioChannelPositionsText(mediaInfo);
            }

            if (audioChannels == null)
            {
                audioChannels = FormatAudioChannelsFromAudioChannels(mediaInfo);
            }

            return(audioChannels ?? 0);
        }
Example #14
0
        private static decimal?FormatAudioChannelsFromAudioChannelPositions(MediaInfoModel mediaInfo)
        {
            if (mediaInfo.AudioChannelPositions == null)
            {
                return(0);
            }

            var match = PositionRegex.Match(mediaInfo.AudioChannelPositions);

            if (match.Success)
            {
                return(decimal.Parse(match.Groups["position"].Value, NumberStyles.Number, CultureInfo.InvariantCulture));
            }

            return(0);
        }
Example #15
0
        public static string FormatVideoCodecLegacy(MediaInfoModel mediaInfo, string sceneName)
        {
            var videoCodec = mediaInfo.VideoCodec;

            if (videoCodec.IsNullOrWhiteSpace())
            {
                return(videoCodec);
            }

            if (videoCodec == "AVC")
            {
                return(GetSceneNameMatch(sceneName, "AVC", "h264", "x264"));
            }

            if (videoCodec == "V_MPEGH/ISO/HEVC" || videoCodec == "HEVC")
            {
                return(GetSceneNameMatch(sceneName, "HEVC", "h265", "x265"));
            }

            if (videoCodec == "MPEG-2 Video")
            {
                return("MPEG2");
            }

            if (videoCodec == "MPEG-4 Visual")
            {
                return(GetSceneNameMatch(sceneName, "DivX", "XviD"));
            }

            if (videoCodec.StartsWithIgnoreCase("XviD"))
            {
                return("XviD");
            }

            if (videoCodec.StartsWithIgnoreCase("DivX"))
            {
                return("DivX");
            }

            if (videoCodec.EqualsIgnoreCase("VC-1"))
            {
                return("VC1");
            }

            return(videoCodec);
        }
Example #16
0
        public static string FormatVideoDynamicRange(MediaInfoModel mediaInfo)
        {
            // assume SDR by default
            var videoDynamicRange = "";

            if (mediaInfo.VideoBitDepth >= 10 &&
                mediaInfo.VideoColourPrimaries.IsNotNullOrWhiteSpace() &&
                mediaInfo.VideoTransferCharacteristics.IsNotNullOrWhiteSpace())
            {
                if (mediaInfo.VideoColourPrimaries.EqualsIgnoreCase(ValidHdrColourPrimaries) &&
                    ValidHdrTransferFunctions.Any(mediaInfo.VideoTransferCharacteristics.Contains))
                {
                    videoDynamicRange = "HDR";
                }
            }

            return(videoDynamicRange);
        }
Example #17
0
        public static string FormatVideoDynamicRange(MediaInfoModel mediaInfo)
        {
            if (mediaInfo.VideoHdrFormat.IsNotNullOrWhiteSpace())
            {
                return(VideoDynamicRangeHdr);
            }

            if (mediaInfo.VideoBitDepth >= 10 &&
                mediaInfo.VideoColourPrimaries.IsNotNullOrWhiteSpace() &&
                mediaInfo.VideoTransferCharacteristics.IsNotNullOrWhiteSpace())
            {
                if (mediaInfo.VideoColourPrimaries.EqualsIgnoreCase(ValidHdrColourPrimaries) &&
                    ValidHdrTransferFunctions.Any(mediaInfo.VideoTransferCharacteristics.Contains))
                {
                    return(VideoDynamicRangeHdr);
                }
            }

            return("");
        }
Example #18
0
        private static decimal?FormatAudioChannelsFromAudioChannelPositionsText(MediaInfoModel mediaInfo)
        {
            var audioChannelPositionsText = mediaInfo.AudioChannelPositionsText;
            var audioChannels             = mediaInfo.AudioChannels;

            if (audioChannelPositionsText.IsNullOrWhiteSpace())
            {
                return(null);
            }

            try
            {
                return(audioChannelPositionsText.ContainsIgnoreCase("LFE") ? audioChannels - 1 + 0.1m : audioChannels);
            }
            catch (Exception e)
            {
                Logger.Warn(e, "Unable to format audio channels using 'AudioChannelPositionsText', with a value of: '{0}'", audioChannelPositionsText);
            }

            return(null);
        }
Example #19
0
        public static string FormatAudioCodec(MediaInfoModel mediaInfo, string sceneName)
        {
            if (mediaInfo.AudioCodecID == null)
            {
                return(FormatAudioCodecLegacy(mediaInfo, sceneName));
            }

            var audioFormat             = mediaInfo.AudioFormat;
            var audioCodecID            = mediaInfo.AudioCodecID ?? string.Empty;
            var audioProfile            = mediaInfo.AudioProfile ?? string.Empty;
            var audioAdditionalFeatures = mediaInfo.AudioAdditionalFeatures ?? string.Empty;
            var audioCodecLibrary       = mediaInfo.AudioCodecLibrary ?? string.Empty;

            if (audioFormat.IsNullOrWhiteSpace())
            {
                return(string.Empty);
            }

            if (audioFormat.EqualsIgnoreCase("AC-3"))
            {
                return("AC3");
            }

            if (audioFormat.EqualsIgnoreCase("E-AC-3"))
            {
                return("EAC3");
            }

            if (audioFormat.EqualsIgnoreCase("AAC"))
            {
                if (audioCodecID == "A_AAC/MPEG4/LC/SBR")
                {
                    return("HE-AAC");
                }

                return("AAC");
            }

            if (audioFormat.EqualsIgnoreCase("DTS"))
            {
                if (audioAdditionalFeatures.StartsWithIgnoreCase("XLL"))
                {
                    if (audioAdditionalFeatures.EndsWithIgnoreCase("X"))
                    {
                        return("DTS-X");
                    }

                    return("DTS-HD MA");
                }

                if (audioAdditionalFeatures.EqualsIgnoreCase("ES"))
                {
                    return("DTS-ES");
                }

                if (audioAdditionalFeatures.EqualsIgnoreCase("XBR"))
                {
                    return("DTS-HD HRA");
                }

                return("DTS");
            }

            if (audioFormat.EqualsIgnoreCase("FLAC"))
            {
                return("FLAC");
            }

            if (audioFormat.Trim().EqualsIgnoreCase("mp3"))
            {
                return("MP3");
            }

            if (audioFormat.EqualsIgnoreCase("MPEG Audio"))
            {
                if (mediaInfo.AudioCodecID == "55" || mediaInfo.AudioCodecID == "A_MPEG/L3" || mediaInfo.AudioProfile == "Layer 3")
                {
                    return("MP3");
                }

                if (mediaInfo.AudioCodecID == "A_MPEG/L2" || mediaInfo.AudioProfile == "Layer 2")
                {
                    return("MP2");
                }
            }

            if (audioFormat.EqualsIgnoreCase("Opus"))
            {
                return("Opus");
            }

            if (audioFormat.EqualsIgnoreCase("PCM"))
            {
                return("PCM");
            }

            if (audioFormat.EqualsIgnoreCase("MLP FBA"))
            {
                if (audioAdditionalFeatures == "16-ch")
                {
                    return("TrueHD Atmos");
                }

                return("TrueHD");
            }

            if (audioFormat.EqualsIgnoreCase("Vorbis"))
            {
                return("Vorbis");
            }

            if (audioFormat == "WMA")
            {
                return("WMA");
            }

            Logger.Debug("Unknown audio format: '{0}' in '{1}'.", string.Join(", ", audioFormat, audioCodecID, audioProfile, audioAdditionalFeatures, audioCodecLibrary), sceneName);

            return(audioFormat);
        }
        public MediaInfoModel GetMediaInfo(string filename)
        {
            if (!_diskProvider.FileExists(filename))
            {
                throw new FileNotFoundException("Media file does not exist: " + filename);
            }

            var mediaInfo = new MediaInfoLib.MediaInfo();

            try
            {
                _logger.Trace("Getting media info from {0}", filename);

                mediaInfo.Option("ParseSpeed", "0.2");
                int open = mediaInfo.Open(filename);

                if (open != 0)
                {
                    int width;
                    int height;
                    int videoBitRate;
                    int audioBitRate;
                    int runTime;
                    int streamCount;
                    int audioChannels;

                    string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List");
                    string scanType  = mediaInfo.Get(StreamKind.Video, 0, "ScanType");
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate);

                    string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate");
                    int    ABindex  = aBitRate.IndexOf(" /");
                    if (ABindex > 0)
                    {
                        aBitRate = aBitRate.Remove(ABindex);
                    }

                    Int32.TryParse(aBitRate, out audioBitRate);
                    Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out runTime);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);

                    string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)");
                    int    ACindex          = audioChannelsStr.IndexOf(" /");
                    if (ACindex > 0)
                    {
                        audioChannelsStr = audioChannelsStr.Remove(ACindex);
                    }

                    string  audioLanguages = mediaInfo.Get(StreamKind.General, 0, "Audio_Language_List");
                    decimal videoFrameRate = Decimal.Parse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"));
                    string  audioProfile   = mediaInfo.Get(StreamKind.Audio, 0, "Format_Profile");

                    int APindex = audioProfile.IndexOf(" /");
                    if (APindex > 0)
                    {
                        audioProfile = audioProfile.Remove(APindex);
                    }

                    Int32.TryParse(audioChannelsStr, out audioChannels);
                    var mediaInfoModel = new MediaInfoModel
                    {
                        VideoCodec       = mediaInfo.Get(StreamKind.Video, 0, "Codec/String"),
                        VideoBitrate     = videoBitRate,
                        Height           = height,
                        Width            = width,
                        AudioFormat      = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
                        AudioBitrate     = audioBitRate,
                        RunTime          = (runTime / 1000),                    //InSeconds
                        AudioStreamCount = streamCount,
                        AudioChannels    = audioChannels,
                        AudioProfile     = audioProfile.Trim(),
                        VideoFps         = videoFrameRate,
                        AudioLanguages   = audioLanguages,
                        Subtitles        = subtitles,
                        ScanType         = scanType
                    };

                    mediaInfo.Close();
                    return(mediaInfoModel);
                }
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Unable to parse media info from file: " + filename, ex);
                mediaInfo.Close();
            }

            return(null);
        }
Example #21
0
        public MediaInfoModel GetMediaInfo(string filename)
        {
            if (!_diskProvider.FileExists(filename))
            {
                throw new FileNotFoundException("Media file does not exist: " + filename);
            }

            MediaInfo mediaInfo = null;

            try
            {
                mediaInfo = new MediaInfo();
                _logger.Debug("Getting media info from {0}", filename);

                if (filename.ToLower().EndsWith(".ts"))
                {
                    mediaInfo.Option("ParseSpeed", "0.3");
                }
                else
                {
                    mediaInfo.Option("ParseSpeed", "0.0");
                }

                int open;

                using (var stream = _diskProvider.OpenReadStream(filename))
                {
                    open = mediaInfo.Open(stream);
                }

                if (open != 0)
                {
                    int audioRuntime;
                    int videoRuntime;
                    int generalRuntime;

                    //Runtime
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime);

                    if (audioRuntime == 0 && videoRuntime == 0 && generalRuntime == 0)
                    {
                        mediaInfo.Option("ParseSpeed", "1.0");

                        using (var stream = _diskProvider.OpenReadStream(filename))
                        {
                            open = mediaInfo.Open(stream);
                        }
                    }
                }

                if (open != 0)
                {
                    int     width;
                    int     height;
                    int     videoBitRate;
                    int     audioBitRate;
                    int     audioRuntime;
                    int     videoRuntime;
                    int     generalRuntime;
                    int     streamCount;
                    int     audioChannels;
                    int     videoBitDepth;
                    decimal videoFrameRate;

                    string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List");
                    string scanType  = mediaInfo.Get(StreamKind.Video, 0, "ScanType");
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate);
                    decimal.TryParse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out videoFrameRate);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitDepth"), out videoBitDepth);

                    //Runtime
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime);

                    string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();

                    int.TryParse(aBitRate, out audioBitRate);
                    int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);


                    string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();

                    var audioChannelPositions     = mediaInfo.Get(StreamKind.Audio, 0, "ChannelPositions/String2");
                    var audioChannelPositionsText = mediaInfo.Get(StreamKind.Audio, 0, "ChannelPositions");

                    string audioLanguages = mediaInfo.Get(StreamKind.General, 0, "Audio_Language_List");

                    string videoProfile = mediaInfo.Get(StreamKind.Video, 0, "Format_Profile").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();
                    string audioProfile = mediaInfo.Get(StreamKind.Audio, 0, "Format_Profile").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();

                    int.TryParse(audioChannelsStr, out audioChannels);
                    var mediaInfoModel = new MediaInfoModel
                    {
                        ContainerFormat           = mediaInfo.Get(StreamKind.General, 0, "Format"),
                        VideoFormat               = mediaInfo.Get(StreamKind.Video, 0, "Format"),
                        VideoCodecID              = mediaInfo.Get(StreamKind.Video, 0, "CodecID"),
                        VideoProfile              = videoProfile,
                        VideoCodecLibrary         = mediaInfo.Get(StreamKind.Video, 0, "Encoded_Library"),
                        VideoBitrate              = videoBitRate,
                        VideoBitDepth             = videoBitDepth,
                        Height                    = height,
                        Width                     = width,
                        AudioFormat               = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
                        AudioCodecID              = mediaInfo.Get(StreamKind.Audio, 0, "CodecID"),
                        AudioProfile              = audioProfile,
                        AudioCodecLibrary         = mediaInfo.Get(StreamKind.Audio, 0, "Encoded_Library"),
                        AudioBitrate              = audioBitRate,
                        RunTime                   = GetBestRuntime(audioRuntime, videoRuntime, generalRuntime),
                        AudioStreamCount          = streamCount,
                        AudioChannels             = audioChannels,
                        AudioChannelPositions     = audioChannelPositions,
                        AudioChannelPositionsText = audioChannelPositionsText,
                        VideoFps                  = videoFrameRate,
                        AudioLanguages            = audioLanguages,
                        Subtitles                 = subtitles,
                        ScanType                  = scanType
                    };

                    return(mediaInfoModel);
                }
                else
                {
                    _logger.Warn("Unable to open media info from file: " + filename);
                }
            }
            catch (DllNotFoundException ex)
            {
                _logger.Error(ex, "mediainfo is required but was not found");
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Unable to parse media info from file: {0}", filename);
            }
            finally
            {
                mediaInfo?.Close();
            }

            return(null);
        }
Example #22
0
        public FileNameSampleService(IBuildFileNames buildFileNames)
        {
            _buildFileNames = buildFileNames;

            _standardSeries = new Series
            {
                SeriesType = SeriesTypes.Standard,
                Title = "Series Title (2010)"
            };

            _dailySeries = new Series
            {
                SeriesType = SeriesTypes.Daily,
                Title = "Series Title (2010)"
            };

            _animeSeries = new Series
            {
                SeriesType = SeriesTypes.Anime,
                Title = "Series Title (2010)"
            };

            _episode1 = new Episode
            {
                SeasonNumber = 1,
                EpisodeNumber = 1,
                Title = "Episode Title (1)",
                AirDate = "2013-10-30",
                AbsoluteEpisodeNumber = 1,
            };

            _episode2 = new Episode
            {
                SeasonNumber = 1,
                EpisodeNumber = 2,
                Title = "Episode Title (2)",
                AbsoluteEpisodeNumber = 2
            };

            _episode3 = new Episode
            {
                SeasonNumber = 1,
                EpisodeNumber = 3,
                Title = "Episode Title (3)",
                AbsoluteEpisodeNumber = 3
            };

            _singleEpisode = new List<Episode> { _episode1 };
            _multiEpisodes = new List<Episode> { _episode1, _episode2, _episode3 };

            var mediaInfo = new MediaInfoModel()
            {
                VideoCodec = "AVC",
                AudioFormat = "DTS",
                AudioLanguages = "English",
                Subtitles = "English/German"
            };

            var mediaInfoAnime = new MediaInfoModel()
            {
                VideoCodec = "AVC",
                AudioFormat = "DTS",
                AudioLanguages = "Japanese",
                Subtitles = "Japanese/English"
            };

            _singleEpisodeFile = new EpisodeFile
            {
                Quality = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv",
                SceneName = "Series.Title.S01E01.720p.HDTV.x264-EVOLVE",
                ReleaseGroup = "RlsGrp",
                MediaInfo = mediaInfo
            };

            _multiEpisodeFile = new EpisodeFile
            {
                Quality = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE.mkv",
                SceneName = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE",
                ReleaseGroup = "RlsGrp",
                MediaInfo = mediaInfo,
            };

            _dailyEpisodeFile = new EpisodeFile
            {
                Quality = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "Series.Title.2013.10.30.HDTV.x264-EVOLVE.mkv",
                SceneName = "Series.Title.2013.10.30.HDTV.x264-EVOLVE",
                ReleaseGroup = "RlsGrp",
                MediaInfo = mediaInfo
            };

            _animeEpisodeFile = new EpisodeFile
            {
                Quality = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "[RlsGroup] Series Title - 001 [720p].mkv",
                SceneName = "[RlsGroup] Series Title - 001 [720p]",
                ReleaseGroup = "RlsGrp",
                MediaInfo = mediaInfoAnime
            };

            _animeMultiEpisodeFile = new EpisodeFile
            {
                Quality = new QualityModel(Quality.HDTV720p, new Revision(2)),
                RelativePath = "[RlsGroup] Series Title - 001 - 103 [720p].mkv",
                SceneName = "[RlsGroup] Series Title - 001 - 103 [720p]",
                ReleaseGroup = "RlsGrp",
                MediaInfo = mediaInfoAnime
            };
        }
Example #23
0
        public MediaInfoModel GetMediaInfo(string filename)
        {
            if (!_diskProvider.FileExists(filename))
            {
                throw new FileNotFoundException("Media file does not exist: " + filename);
            }

            MediaInfo mediaInfo = null;

            // TODO: Cache media info by path, mtime and length so we don't need to read files multiple times

            try
            {
                mediaInfo = new MediaInfo();
                _logger.Debug("Getting media info from {0}", filename);

                if (filename.ToLower().EndsWith(".ts"))
                {
                    // For .ts files we often have to scan more of the file to get all the info we need
                    mediaInfo.Option("ParseSpeed", "0.3");
                }
                else
                {
                    mediaInfo.Option("ParseSpeed", "0.0");
                }

                int open;

                using (var stream = _diskProvider.OpenReadStream(filename))
                {
                    open = mediaInfo.Open(stream);
                }

                if (open != 0)
                {
                    int audioRuntime;
                    int videoRuntime;
                    int generalRuntime;

                    // Runtime
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime);

                    // Audio Channels
                    var audioChannelsStr      = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();
                    var audioChannelPositions = mediaInfo.Get(StreamKind.Audio, 0, "ChannelPositions/String2");
                    int.TryParse(audioChannelsStr, out var audioChannels);

                    if (audioRuntime == 0 && videoRuntime == 0 && generalRuntime == 0)
                    {
                        // No runtime, ask mediainfo to scan the whole file
                        mediaInfo.Option("ParseSpeed", "1.0");

                        using (var stream = _diskProvider.OpenReadStream(filename))
                        {
                            open = mediaInfo.Open(stream);
                        }
                    }
                    else if (audioChannels > 2 && audioChannelPositions.IsNullOrWhiteSpace())
                    {
                        // Some files with DTS don't have ChannelPositions unless more of the file is scanned
                        mediaInfo.Option("ParseSpeed", "0.3");

                        using (var stream = _diskProvider.OpenReadStream(filename))
                        {
                            open = mediaInfo.Open(stream);
                        }
                    }
                }

                if (open != 0)
                {
                    int     width;
                    int     height;
                    int     videoBitRate;
                    int     audioBitRate;
                    int     audioRuntime;
                    int     videoRuntime;
                    int     generalRuntime;
                    int     streamCount;
                    int     audioChannels;
                    int     audioChannelsOrig;
                    int     videoBitDepth;
                    decimal videoFrameRate;
                    int     videoMultiViewCount;

                    string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List");
                    string scanType  = mediaInfo.Get(StreamKind.Video, 0, "ScanType");
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate);
                    if (videoBitRate <= 0)
                    {
                        int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate_Nominal"), out videoBitRate);
                    }
                    decimal.TryParse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out videoFrameRate);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitDepth"), out videoBitDepth);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "MultiView_Count"), out videoMultiViewCount);

                    //Runtime
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime);

                    string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();

                    int.TryParse(aBitRate, out audioBitRate);
                    int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);


                    var audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();
                    int.TryParse(audioChannelsStr, out audioChannels);

                    var audioChannelsStrOrig = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)_Original").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();
                    int.TryParse(audioChannelsStrOrig, out audioChannelsOrig);

                    var audioChannelPositionsText     = mediaInfo.Get(StreamKind.Audio, 0, "ChannelPositions");
                    var audioChannelPositionsTextOrig = mediaInfo.Get(StreamKind.Audio, 0, "ChannelPositions_Original");
                    var audioChannelPositions         = mediaInfo.Get(StreamKind.Audio, 0, "ChannelPositions/String2");

                    string audioLanguages = mediaInfo.Get(StreamKind.General, 0, "Audio_Language_List");

                    string videoProfile = mediaInfo.Get(StreamKind.Video, 0, "Format_Profile").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();
                    string audioProfile = mediaInfo.Get(StreamKind.Audio, 0, "Format_Profile").Split(new string[] { " /" }, StringSplitOptions.None)[0].Trim();

                    var mediaInfoModel = new MediaInfoModel
                    {
                        ContainerFormat              = mediaInfo.Get(StreamKind.General, 0, "Format"),
                        VideoFormat                  = mediaInfo.Get(StreamKind.Video, 0, "Format"),
                        VideoCodecID                 = mediaInfo.Get(StreamKind.Video, 0, "CodecID"),
                        VideoProfile                 = videoProfile,
                        VideoCodecLibrary            = mediaInfo.Get(StreamKind.Video, 0, "Encoded_Library"),
                        VideoBitrate                 = videoBitRate,
                        VideoBitDepth                = videoBitDepth,
                        VideoMultiViewCount          = videoMultiViewCount,
                        VideoColourPrimaries         = mediaInfo.Get(StreamKind.Video, 0, "colour_primaries"),
                        VideoTransferCharacteristics = mediaInfo.Get(StreamKind.Video, 0, "transfer_characteristics"),
                        Height                             = height,
                        Width                              = width,
                        AudioFormat                        = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
                        AudioCodecID                       = mediaInfo.Get(StreamKind.Audio, 0, "CodecID"),
                        AudioProfile                       = audioProfile,
                        AudioCodecLibrary                  = mediaInfo.Get(StreamKind.Audio, 0, "Encoded_Library"),
                        AudioAdditionalFeatures            = mediaInfo.Get(StreamKind.Audio, 0, "Format_AdditionalFeatures"),
                        AudioBitrate                       = audioBitRate,
                        RunTime                            = GetBestRuntime(audioRuntime, videoRuntime, generalRuntime),
                        AudioStreamCount                   = streamCount,
                        AudioChannelsContainer             = audioChannels,
                        AudioChannelsStream                = audioChannelsOrig,
                        AudioChannelPositions              = audioChannelPositions,
                        AudioChannelPositionsTextContainer = audioChannelPositionsText,
                        AudioChannelPositionsTextStream    = audioChannelPositionsTextOrig,
                        VideoFps                           = videoFrameRate,
                        AudioLanguages                     = audioLanguages,
                        Subtitles                          = subtitles,
                        ScanType                           = scanType,
                        SchemaRevision                     = CURRENT_MEDIA_INFO_SCHEMA_REVISION
                    };

                    return(mediaInfoModel);
                }
                else
                {
                    _logger.Warn("Unable to open media info from file: " + filename);
                }
            }
            catch (DllNotFoundException ex)
            {
                _logger.Error(ex, "mediainfo is required but was not found");
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Unable to parse media info from file: {0}", filename);
            }
            finally
            {
                mediaInfo?.Close();
            }

            return(null);
        }
Example #24
0
        public static string FormatAudioCodec(MediaInfoModel mediaInfo, string sceneName)
        {
            if (mediaInfo.AudioFormat == null)
            {
                return(null);
            }

            var audioFormat  = mediaInfo.AudioFormat;
            var audioCodecID = mediaInfo.AudioCodecID ?? string.Empty;
            var audioProfile = mediaInfo.AudioProfile ?? string.Empty;

            if (audioFormat.Empty())
            {
                return(string.Empty);
            }

            // see definitions here https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/codec_desc.c
            if (audioCodecID == "thd+")
            {
                return("TrueHD Atmos");
            }

            if (audioFormat == "truehd")
            {
                return("TrueHD");
            }

            if (audioFormat == "flac")
            {
                return("FLAC");
            }

            if (audioFormat == "dts")
            {
                if (audioProfile == "DTS:X")
                {
                    return("DTS-X");
                }

                if (audioProfile == "DTS-HD MA")
                {
                    return("DTS-HD MA");
                }

                if (audioProfile == "DTS-ES")
                {
                    return("DTS-ES");
                }

                if (audioProfile == "DTS-HD HRA")
                {
                    return("DTS-HD HRA");
                }

                if (audioProfile == "DTS Express")
                {
                    return("DTS Express");
                }

                if (audioProfile == "DTS 96/24")
                {
                    return("DTS 96/24");
                }

                return("DTS");
            }

            if (audioCodecID == "ec+3")
            {
                return("EAC3 Atmos");
            }

            if (audioFormat == "eac3")
            {
                return("EAC3");
            }

            if (audioFormat == "ac3")
            {
                return("AC3");
            }

            if (audioFormat == "aac")
            {
                if (audioCodecID == "A_AAC/MPEG4/LC/SBR")
                {
                    return("HE-AAC");
                }

                return("AAC");
            }

            if (audioFormat == "mp3")
            {
                return("MP3");
            }

            if (audioFormat == "mp2")
            {
                return("MP2");
            }

            if (audioFormat == "opus")
            {
                return("Opus");
            }

            if (audioFormat.StartsWith("pcm_") || audioFormat.StartsWith("adpcm_"))
            {
                return("PCM");
            }

            if (audioFormat == "vorbis")
            {
                return("Vorbis");
            }

            if (audioFormat == "wmav1" ||
                audioFormat == "wmav2")
            {
                return("WMA");
            }

            Logger.Debug()
            .Message("Unknown audio format: '{0}' in '{1}'.", mediaInfo.RawStreamData, sceneName)
            .WriteSentryWarn("UnknownAudioFormatFFProbe", mediaInfo.ContainerFormat, mediaInfo.AudioFormat, audioCodecID)
            .Write();

            return(mediaInfo.AudioFormat);
        }
Example #25
0
        public MediaInfoModel GetMediaInfo(string filename)
        {
            if (!_diskProvider.FileExists(filename))
            {
                throw new FileNotFoundException("Media file does not exist: " + filename);
            }

            MediaInfoLib.MediaInfo mediaInfo = null;

            try
            {
                mediaInfo = new MediaInfoLib.MediaInfo();
                _logger.Debug("Getting media info from {0}", filename);

                mediaInfo.Option("ParseSpeed", "0.2");
                int open = mediaInfo.Open(filename);

                if (open != 0)
                {
                    int     width;
                    int     height;
                    int     videoBitRate;
                    int     audioBitRate;
                    int     audioRuntime;
                    int     videoRuntime;
                    int     generalRuntime;
                    int     streamCount;
                    int     audioChannels;
                    decimal videoFrameRate;

                    string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List");
                    string scanType  = mediaInfo.Get(StreamKind.Video, 0, "ScanType");
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate);
                    Decimal.TryParse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out videoFrameRate);

                    //Runtime
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime);
                    Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime);

                    string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate");
                    int    aBindex  = aBitRate.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);
                    if (aBindex > 0)
                    {
                        aBitRate = aBitRate.Remove(aBindex);
                    }

                    Int32.TryParse(aBitRate, out audioBitRate);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);


                    string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)");
                    int    aCindex          = audioChannelsStr.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);
                    if (aCindex > 0)
                    {
                        audioChannelsStr = audioChannelsStr.Remove(aCindex);
                    }

                    string audioLanguages = mediaInfo.Get(StreamKind.General, 0, "Audio_Language_List");
                    string audioProfile   = mediaInfo.Get(StreamKind.Audio, 0, "Format_Profile");

                    int aPindex = audioProfile.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);
                    if (aPindex > 0)
                    {
                        audioProfile = audioProfile.Remove(aPindex);
                    }

                    Int32.TryParse(audioChannelsStr, out audioChannels);
                    var mediaInfoModel = new MediaInfoModel
                    {
                        VideoCodec       = mediaInfo.Get(StreamKind.Video, 0, "Codec/String"),
                        VideoBitrate     = videoBitRate,
                        Height           = height,
                        Width            = width,
                        AudioFormat      = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
                        AudioBitrate     = audioBitRate,
                        RunTime          = GetBestRuntime(audioRuntime, videoRuntime, generalRuntime),
                        AudioStreamCount = streamCount,
                        AudioChannels    = audioChannels,
                        AudioProfile     = audioProfile.Trim(),
                        VideoFps         = videoFrameRate,
                        AudioLanguages   = audioLanguages,
                        Subtitles        = subtitles,
                        ScanType         = scanType
                    };

                    return(mediaInfoModel);
                }
            }
            catch (DllNotFoundException ex)
            {
                _logger.ErrorException("mediainfo is required but was not found", ex);
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Unable to parse media info from file: " + filename, ex);
            }
            finally
            {
                if (mediaInfo != null)
                {
                    mediaInfo.Close();
                }
            }

            return(null);
        }
        public MediaInfoModel GetMediaInfo(string filename)
        {
            if (!_diskProvider.FileExists(filename))
                throw new FileNotFoundException("Media file does not exist: " + filename);

            var mediaInfo = new MediaInfoLib.MediaInfo();

            try
            {
                _logger.Trace("Getting media info from {0}", filename);

                mediaInfo.Option("ParseSpeed", "0.2");
                int open = mediaInfo.Open(filename);

                if (open != 0)
                {
                    int width;
                    int height;
                    int videoBitRate;
                    int audioBitRate;
                    int runTime;
                    int streamCount;
                    int audioChannels;

                    string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List");
                    string scanType = mediaInfo.Get(StreamKind.Video, 0, "ScanType");
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate);

                    string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate");
                    int ABindex = aBitRate.IndexOf(" /");
                    if (ABindex > 0)
                        aBitRate = aBitRate.Remove(ABindex);

                    Int32.TryParse(aBitRate, out audioBitRate);
                    Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out runTime);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);

                    string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)");
                    int ACindex = audioChannelsStr.IndexOf(" /");
                    if (ACindex > 0)
                        audioChannelsStr = audioChannelsStr.Remove(ACindex);

                    string audioLanguages = mediaInfo.Get(StreamKind.General, 0, "Audio_Language_List");
                    decimal videoFrameRate = Decimal.Parse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"));
                    string audioProfile = mediaInfo.Get(StreamKind.Audio, 0, "Format_Profile");

                    int APindex = audioProfile.IndexOf(" /");
                    if (APindex > 0)
                        audioProfile = audioProfile.Remove(APindex);

                    Int32.TryParse(audioChannelsStr, out audioChannels);
                    var mediaInfoModel = new MediaInfoModel
                                                {
                                                    VideoCodec = mediaInfo.Get(StreamKind.Video, 0, "Codec/String"),
                                                    VideoBitrate = videoBitRate,
                                                    Height = height,
                                                    Width = width,
                                                    AudioFormat = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
                                                    AudioBitrate = audioBitRate,
                                                    RunTime = (runTime / 1000), //InSeconds
                                                    AudioStreamCount = streamCount,
                                                    AudioChannels = audioChannels,
                                                    AudioProfile = audioProfile.Trim(),
                                                    VideoFps = videoFrameRate,
                                                    AudioLanguages = audioLanguages,
                                                    Subtitles = subtitles,
                                                    ScanType = scanType
                                                };

                    mediaInfo.Close();
                    return mediaInfoModel;
                }
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Unable to parse media info from file: " + filename, ex);
                mediaInfo.Close();
            }

            return null;
        }
Example #27
0
 public static string FormatVideoDynamicRange(MediaInfoModel mediaInfo)
 {
     return(mediaInfo.GetHdrFormat() == HdrFormat.None ? "" : "HDR");
 }
Example #28
0
        private static decimal?FormatAudioChannelsFromAudioChannelPositions(MediaInfoModel mediaInfo)
        {
            var audioChannelPositions = mediaInfo.AudioChannelPositions;
            var audioFormat           = mediaInfo.AudioFormat;

            if (audioChannelPositions.IsNullOrWhiteSpace())
            {
                return(null);
            }

            try
            {
                if (audioChannelPositions.Contains("+"))
                {
                    return(audioChannelPositions.Split('+')
                           .Sum(s => decimal.Parse(s.Trim(), CultureInfo.InvariantCulture)));
                }

                if (audioChannelPositions.Contains("/"))
                {
                    var channelStringList = Regex.Replace(audioChannelPositions,
                                                          @"^\d+\sobjects",
                                                          "",
                                                          RegexOptions.Compiled | RegexOptions.IgnoreCase)
                                            .Replace("Object Based / ", "")
                                            .Split(new string[] { " / " }, StringSplitOptions.RemoveEmptyEntries)
                                            .FirstOrDefault()
                                            ?.Split('/');

                    var positions = default(decimal);

                    if (channelStringList == null)
                    {
                        return(0);
                    }

                    foreach (var channel in channelStringList)
                    {
                        var channelSplit = channel.Split(new string[] { "." }, StringSplitOptions.None);

                        if (channelSplit.Length == 3)
                        {
                            positions += decimal.Parse(string.Format("{0}.{1}", channelSplit[1], channelSplit[2]), CultureInfo.InvariantCulture);
                        }
                        else
                        {
                            positions += decimal.Parse(channel, CultureInfo.InvariantCulture);
                        }
                    }

                    return(positions);
                }
            }
            catch (Exception ex)
            {
                Logger.Warn()
                .Message("Unable to format audio channels using 'AudioChannelPositions', with a value of: '{0}' and '{1}'. Error {2}", audioChannelPositions, mediaInfo.AudioChannelPositionsTextContainer, ex.Message)
                .WriteSentryWarn("UnknownAudioChannelFormat", audioChannelPositions, mediaInfo.AudioChannelPositionsTextContainer)
                .Write();
            }

            return(null);
        }
Example #29
0
        public static string FormatVideoCodec(MediaInfoModel mediaInfo, string sceneName)
        {
            if (mediaInfo.VideoFormat == null)
            {
                return(null);
            }

            var videoFormat  = mediaInfo.VideoFormat;
            var videoCodecID = mediaInfo.VideoCodecID ?? string.Empty;

            var result = videoFormat.Trim();

            if (videoFormat.Empty())
            {
                return(result);
            }

            // see definitions here: https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/codec_desc.c
            if (videoCodecID == "x264")
            {
                return("x264");
            }

            if (videoFormat == "h264")
            {
                return(GetSceneNameMatch(sceneName, "AVC", "x264", "h264"));
            }

            if (videoCodecID == "x265")
            {
                return("x265");
            }

            if (videoFormat == "hevc")
            {
                return(GetSceneNameMatch(sceneName, "HEVC", "x265", "h265"));
            }

            if (videoFormat == "mpeg2video")
            {
                return("MPEG2");
            }

            if (videoFormat == "mpeg1video")
            {
                return("MPEG");
            }

            if (videoFormat == "mpeg4" || videoFormat.Contains("msmpeg4"))
            {
                if (videoCodecID == "XVID")
                {
                    return("XviD");
                }

                if (videoCodecID == "DIV3" ||
                    videoCodecID == "DIVX" ||
                    videoCodecID == "DX50")
                {
                    return("DivX");
                }

                return("");
            }

            if (videoFormat == "vc1")
            {
                return("VC1");
            }

            if (videoFormat == "av1")
            {
                return("AV1");
            }

            if (videoFormat == "vp6" ||
                videoFormat == "vp7" ||
                videoFormat == "vp8" ||
                videoFormat == "vp9")
            {
                return(videoFormat.ToUpperInvariant());
            }

            if (videoFormat == "wmv1" ||
                videoFormat == "wmv2")
            {
                return("WMV");
            }

            if (videoFormat == "qtrle" ||
                videoFormat == "rpza" ||
                videoFormat == "rv10" ||
                videoFormat == "rv20" ||
                videoFormat == "rv30" ||
                videoFormat == "rv40")
            {
                return("");
            }

            Logger.Debug()
            .Message("Unknown video format: '{0}' in '{1}'.", mediaInfo.RawStreamData, sceneName)
            .WriteSentryWarn("UnknownVideoFormatFFProbe", mediaInfo.ContainerFormat, videoFormat, videoCodecID)
            .Write();

            return(result);
        }
Example #30
0
        public static string FormatAudioCodec(MediaInfoModel mediaInfo, string sceneName)
        {
            if (mediaInfo.AudioCodecID == null)
            {
                return(FormatAudioCodecLegacy(mediaInfo, sceneName));
            }

            var audioFormat             = mediaInfo.AudioFormat.Trim().Split(new[] { " / " }, StringSplitOptions.RemoveEmptyEntries);
            var audioCodecID            = mediaInfo.AudioCodecID ?? string.Empty;
            var audioProfile            = mediaInfo.AudioProfile ?? string.Empty;
            var audioCodecLibrary       = mediaInfo.AudioCodecLibrary ?? string.Empty;
            var splitAdditionalFeatures = (mediaInfo.AudioAdditionalFeatures ?? string.Empty).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (audioFormat.Empty())
            {
                return(string.Empty);
            }

            if (audioFormat.ContainsIgnoreCase("Atmos"))
            {
                return("TrueHD Atmos");
            }

            if (audioFormat.ContainsIgnoreCase("MLP FBA"))
            {
                if (splitAdditionalFeatures.ContainsIgnoreCase("16-ch"))
                {
                    return("TrueHD Atmos");
                }

                return("TrueHD");
            }

            if (audioFormat.ContainsIgnoreCase("TrueHD"))
            {
                return("TrueHD");
            }

            if (audioFormat.ContainsIgnoreCase("FLAC"))
            {
                return("FLAC");
            }

            if (audioFormat.ContainsIgnoreCase("DTS"))
            {
                if (splitAdditionalFeatures.ContainsIgnoreCase("XLL"))
                {
                    if (splitAdditionalFeatures.ContainsIgnoreCase("X"))
                    {
                        return("DTS-X");
                    }

                    return("DTS-HD MA");
                }

                if (splitAdditionalFeatures.ContainsIgnoreCase("ES"))
                {
                    return("DTS-ES");
                }

                if (splitAdditionalFeatures.ContainsIgnoreCase("XBR"))
                {
                    return("DTS-HD HRA");
                }

                return("DTS");
            }

            if (audioFormat.ContainsIgnoreCase("E-AC-3"))
            {
                if (splitAdditionalFeatures.ContainsIgnoreCase("JOC"))
                {
                    return("EAC3 Atmos");
                }

                return("EAC3");
            }

            if (audioFormat.ContainsIgnoreCase("AC-3"))
            {
                return("AC3");
            }

            if (audioFormat.ContainsIgnoreCase("AAC"))
            {
                if (audioCodecID == "A_AAC/MPEG4/LC/SBR")
                {
                    return("HE-AAC");
                }

                return("AAC");
            }

            if (audioFormat.ContainsIgnoreCase("mp3"))
            {
                return("MP3");
            }

            if (audioFormat.ContainsIgnoreCase("MPEG Audio"))
            {
                if (mediaInfo.AudioCodecID == "55" || mediaInfo.AudioCodecID == "A_MPEG/L3" || mediaInfo.AudioProfile == "Layer 3")
                {
                    return("MP3");
                }

                if (mediaInfo.AudioCodecID == "A_MPEG/L2" || mediaInfo.AudioProfile == "Layer 2")
                {
                    return("MP2");
                }
            }

            if (audioFormat.ContainsIgnoreCase("Opus"))
            {
                return("Opus");
            }

            if (audioFormat.ContainsIgnoreCase("PCM"))
            {
                return("PCM");
            }

            if (audioFormat.ContainsIgnoreCase("ADPCM"))
            {
                return("PCM");
            }

            if (audioFormat.ContainsIgnoreCase("Vorbis"))
            {
                return("Vorbis");
            }

            if (audioFormat.ContainsIgnoreCase("WMA"))
            {
                return("WMA");
            }

            if (audioFormat.ContainsIgnoreCase("A_QUICKTIME"))
            {
                return("");
            }

            Logger.Debug()
            .Message("Unknown audio format: '{0}' in '{1}'.", string.Join(", ", mediaInfo.AudioFormat, audioCodecID, audioProfile, audioCodecLibrary, mediaInfo.AudioAdditionalFeatures), sceneName)
            .WriteSentryWarn("UnknownAudioFormat", mediaInfo.ContainerFormat, mediaInfo.AudioFormat, audioCodecID)
            .Write();

            return(mediaInfo.AudioFormat);
        }
Example #31
0
        public static string FormatVideoCodec(MediaInfoModel mediaInfo, string sceneName)
        {
            if (mediaInfo.VideoFormat == null)
            {
                return(FormatVideoCodecLegacy(mediaInfo, sceneName));
            }

            var videoFormat       = mediaInfo.VideoFormat.Trim().Split(new[] { " / " }, StringSplitOptions.RemoveEmptyEntries);
            var videoCodecID      = mediaInfo.VideoCodecID ?? string.Empty;
            var videoProfile      = mediaInfo.VideoProfile ?? string.Empty;
            var videoCodecLibrary = mediaInfo.VideoCodecLibrary ?? string.Empty;

            var result = mediaInfo.VideoFormat.Trim();

            if (videoFormat.Empty())
            {
                return(result);
            }

            if (videoFormat.ContainsIgnoreCase("x264"))
            {
                return("x264");
            }

            if (videoFormat.ContainsIgnoreCase("AVC") || videoFormat.ContainsIgnoreCase("V.MPEG4/ISO/AVC"))
            {
                if (videoCodecLibrary.StartsWithIgnoreCase("x264"))
                {
                    return("x264");
                }

                return(GetSceneNameMatch(sceneName, "AVC", "x264", "h264"));
            }

            if (videoFormat.ContainsIgnoreCase("HEVC") || videoFormat.ContainsIgnoreCase("V_MPEGH/ISO/HEVC"))
            {
                if (videoCodecLibrary.StartsWithIgnoreCase("x265"))
                {
                    return("x265");
                }

                return(GetSceneNameMatch(sceneName, "HEVC", "x265", "h265"));
            }

            if (videoFormat.ContainsIgnoreCase("MPEG Video"))
            {
                if (videoCodecID == "2" || videoCodecID == "V_MPEG2")
                {
                    return("MPEG2");
                }

                if (videoCodecID.IsNullOrWhiteSpace())
                {
                    return("MPEG");
                }
            }

            if (videoFormat.ContainsIgnoreCase("MPEG-2 Video"))
            {
                return("MPEG2");
            }

            if (videoFormat.ContainsIgnoreCase("MPEG-4 Visual"))
            {
                if (videoCodecID.ContainsIgnoreCase("XVID") ||
                    videoCodecLibrary.StartsWithIgnoreCase("XviD"))
                {
                    return("XviD");
                }

                if (videoCodecID.ContainsIgnoreCase("DIV3") ||
                    videoCodecID.ContainsIgnoreCase("DIVX") ||
                    videoCodecID.ContainsIgnoreCase("DX50") ||
                    videoCodecLibrary.StartsWithIgnoreCase("DivX"))
                {
                    return("DivX");
                }
            }

            if (videoFormat.ContainsIgnoreCase("MPEG-4 Visual") || videoFormat.ContainsIgnoreCase("mp4v"))
            {
                result = GetSceneNameMatch(sceneName, "XviD", "DivX", "");
                if (result.IsNotNullOrWhiteSpace())
                {
                    return(result);
                }

                if (videoCodecLibrary.Contains("Lavc"))
                {
                    return(""); // libavcodec mpeg-4
                }

                if (videoCodecLibrary.Contains("em4v"))
                {
                    return(""); // NeroDigital
                }

                if (videoCodecLibrary.Contains("Intel(R) IPP"))
                {
                    return(""); // Intel(R) IPP
                }

                if (videoCodecLibrary.Contains("ZJMedia") ||
                    videoCodecLibrary.Contains("DigiArty"))
                {
                    return(""); // Other
                }

                if (string.IsNullOrEmpty(videoCodecLibrary))
                {
                    return(""); // Unknown mp4v
                }
            }

            if (videoFormat.ContainsIgnoreCase("VC-1"))
            {
                return("VC1");
            }

            if (videoFormat.ContainsIgnoreCase("AV1"))
            {
                return("AV1");
            }

            if (videoFormat.ContainsIgnoreCase("VP6") || videoFormat.ContainsIgnoreCase("VP7") ||
                videoFormat.ContainsIgnoreCase("VP8") || videoFormat.ContainsIgnoreCase("VP9"))
            {
                return(videoFormat.First().ToUpperInvariant());
            }

            if (videoFormat.ContainsIgnoreCase("WMV1") || videoFormat.ContainsIgnoreCase("WMV2"))
            {
                return("WMV");
            }

            if (videoFormat.ContainsIgnoreCase("DivX") || videoFormat.ContainsIgnoreCase("div3"))
            {
                return("DivX");
            }

            if (videoFormat.ContainsIgnoreCase("XviD"))
            {
                return("XviD");
            }

            if (videoFormat.ContainsIgnoreCase("V_QUICKTIME") ||
                videoFormat.ContainsIgnoreCase("RealVideo 4"))
            {
                return("");
            }

            if (videoFormat.ContainsIgnoreCase("mp42") ||
                videoFormat.ContainsIgnoreCase("mp43"))
            {
                // MS old DivX competitor
                return("");
            }

            Logger.Debug()
            .Message("Unknown video format: '{0}' in '{1}'.", string.Join(", ", mediaInfo.VideoFormat, videoCodecID, videoProfile, videoCodecLibrary), sceneName)
            .WriteSentryWarn("UnknownVideoFormat", mediaInfo.ContainerFormat, mediaInfo.VideoFormat, videoCodecID)
            .Write();

            return(result);
        }
        public MediaInfoModel GetMediaInfo(string filename)
        {
            if (!_diskProvider.FileExists(filename))
                throw new FileNotFoundException("Media file does not exist: " + filename);

            MediaInfoLib.MediaInfo mediaInfo = null;

            try
            {
                mediaInfo = new MediaInfoLib.MediaInfo();
                _logger.Trace("Getting media info from {0}", filename);

                mediaInfo.Option("ParseSpeed", "0.2");
                int open = mediaInfo.Open(filename);

                if (open != 0)
                {
                    int width;
                    int height;
                    int videoBitRate;
                    int audioBitRate;
                    int audioRuntime;
                    int videoRuntime;
                    int generalRuntime;
                    int streamCount;
                    int audioChannels;
                    decimal videoFrameRate;

                    string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List");
                    string scanType = mediaInfo.Get(StreamKind.Video, 0, "ScanType");
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate);
                    Decimal.TryParse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"), out videoFrameRate);

                    //Runtime
                    Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime);
                    Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime);

                    string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate");
                    int aBindex = aBitRate.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);
                    if (aBindex > 0)
                        aBitRate = aBitRate.Remove(aBindex);

                    Int32.TryParse(aBitRate, out audioBitRate);
                    Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);
                    

                    string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)");
                    int aCindex = audioChannelsStr.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);
                    if (aCindex > 0)
                        audioChannelsStr = audioChannelsStr.Remove(aCindex);

                    string audioLanguages = mediaInfo.Get(StreamKind.General, 0, "Audio_Language_List");
                    string audioProfile = mediaInfo.Get(StreamKind.Audio, 0, "Format_Profile");

                    int aPindex = audioProfile.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);
                    if (aPindex > 0)
                        audioProfile = audioProfile.Remove(aPindex);

                    Int32.TryParse(audioChannelsStr, out audioChannels);
                    var mediaInfoModel = new MediaInfoModel
                                                {
                                                    VideoCodec = mediaInfo.Get(StreamKind.Video, 0, "Codec/String"),
                                                    VideoBitrate = videoBitRate,
                                                    Height = height,
                                                    Width = width,
                                                    AudioFormat = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
                                                    AudioBitrate = audioBitRate,
                                                    RunTime = GetBestRuntime(audioRuntime, videoRuntime, generalRuntime),
                                                    AudioStreamCount = streamCount,
                                                    AudioChannels = audioChannels,
                                                    AudioProfile = audioProfile.Trim(),
                                                    VideoFps = videoFrameRate,
                                                    AudioLanguages = audioLanguages,
                                                    Subtitles = subtitles,
                                                    ScanType = scanType
                                                };

                    return mediaInfoModel;
                }
            }
            catch (DllNotFoundException ex)
            {
                _logger.ErrorException("mediainfo is required but was not found", ex);
                throw;
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Unable to parse media info from file: " + filename, ex);
            }
            finally
            {
                if (mediaInfo != null)
                {
                    mediaInfo.Close();
                }
            }

            return null;
        }
Example #33
0
 public static string FormatVideoDynamicRange(MediaInfoModel mediaInfo)
 {
     return(mediaInfo.VideoHdrFormat != HdrFormat.None ? VideoDynamicRangeHdr : "");
 }
        public MediaInfoModel GetMediaInfo(string filename)
        {
            if (!_diskProvider.FileExists(filename))
            {
                throw new FileNotFoundException("Media file does not exist: " + filename);
            }

            MediaInfo mediaInfo = null;

            try
            {
                mediaInfo = new MediaInfo();
                _logger.Debug("Getting media info from {0}", filename);

                if (filename.ToLower().EndsWith(".ts"))
                {
                    mediaInfo.Option("ParseSpeed", "0.3");
                }
                else
                {
                    mediaInfo.Option("ParseSpeed", "0.0");
                }

                int open;

                using (var stream = _diskProvider.OpenReadStream(filename))
                {
                    open = mediaInfo.Open(stream);
                }

                if (open != 0)
                {
                    int audioRuntime;
                    int videoRuntime;
                    int generalRuntime;

                    //Runtime
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime);

                    if (audioRuntime == 0 && videoRuntime == 0 && generalRuntime == 0)
                    {
                        mediaInfo.Option("ParseSpeed", "1.0");

                        using (var stream = _diskProvider.OpenReadStream(filename))
                        {
                            open = mediaInfo.Open(stream);
                        }
                    }
                }

                if (open != 0)
                {
                    int width;
                    int height;
                    int videoBitRate;
                    int audioBitRate;
                    int audioRuntime;
                    int videoRuntime;
                    int generalRuntime;
                    int streamCount;
                    int audioChannels;
                    int videoBitDepth;
                    decimal videoFrameRate;

                    string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List");
                    string scanType = mediaInfo.Get(StreamKind.Video, 0, "ScanType");
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate);
                    decimal.TryParse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out videoFrameRate);
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitDepth"), out videoBitDepth);

                    //Runtime
                    int.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime);
                    int.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime);

                    string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate");
                    int aBindex = aBitRate.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);
                    if (aBindex > 0)
                    {
                        aBitRate = aBitRate.Remove(aBindex);
                    }

                    int.TryParse(aBitRate, out audioBitRate);
                    int.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);

                    string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)");
                    int aCindex = audioChannelsStr.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);

                    if (aCindex > 0)
                    {
                        audioChannelsStr = audioChannelsStr.Remove(aCindex);
                    }

                    var audioChannelPositions = mediaInfo.Get(StreamKind.Audio, 0, "ChannelPositions/String2");
                    var audioChannelPositionsText = mediaInfo.Get(StreamKind.Audio, 0, "ChannelPositions");

                    string audioLanguages = mediaInfo.Get(StreamKind.General, 0, "Audio_Language_List");
                    string audioProfile = mediaInfo.Get(StreamKind.Audio, 0, "Format_Profile");

                    int aPindex = audioProfile.IndexOf(" /", StringComparison.InvariantCultureIgnoreCase);

                    if (aPindex > 0)
                    {
                        audioProfile = audioProfile.Remove(aPindex);
                    }

                    int.TryParse(audioChannelsStr, out audioChannels);
                    var mediaInfoModel = new MediaInfoModel
                                                {
                                                    VideoCodec = mediaInfo.Get(StreamKind.Video, 0, "Codec/String"),
                                                    VideoBitrate = videoBitRate,
                                                    VideoBitDepth = videoBitDepth,
                                                    Height = height,
                                                    Width = width,
                                                    AudioFormat = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
                                                    AudioBitrate = audioBitRate,
                                                    RunTime = GetBestRuntime(audioRuntime, videoRuntime, generalRuntime),
                                                    AudioStreamCount = streamCount,
                                                    AudioChannels = audioChannels,
                                                    AudioChannelPositions = audioChannelPositions,
                                                    AudioChannelPositionsText = audioChannelPositionsText,
                                                    AudioProfile = audioProfile.Trim(),
                                                    VideoFps = videoFrameRate,
                                                    AudioLanguages = audioLanguages,
                                                    Subtitles = subtitles,
                                                    ScanType = scanType
                                                };

                    return mediaInfoModel;
                }
                else
                {
                    _logger.Warn("Unable to open media info from file: " + filename);
                }
            }
            catch (DllNotFoundException ex)
            {
                _logger.Error(ex, "mediainfo is required but was not found");
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Unable to parse media info from file: " + filename);
            }
            finally
            {
                if (mediaInfo != null)
                {
                    mediaInfo.Close();
                }
            }

            return null;
        }