internal static void ParseInputLine(IResourceAccessor file, string inputLine, ref MetadataContainer info) { inputLine = inputLine.Trim(); int inputPos = inputLine.IndexOf("Input #0", StringComparison.InvariantCultureIgnoreCase); string ffmContainer = inputLine.Substring(inputPos + 10, inputLine.IndexOf(",", inputPos + 11) - 10).Trim(); if (info.IsAudio(Editions.DEFAULT_EDITION)) { info.Metadata[Editions.DEFAULT_EDITION].AudioContainerType = FFMpegParseAudioContainer.ParseAudioContainer(ffmContainer, file); } else if (info.IsVideo(Editions.DEFAULT_EDITION)) { info.Metadata[Editions.DEFAULT_EDITION].VideoContainerType = FFMpegParseVideoContainer.ParseVideoContainer(ffmContainer, file); } else if (info.IsImage(Editions.DEFAULT_EDITION)) { info.Metadata[Editions.DEFAULT_EDITION].ImageContainerType = FFMpegParseImageContainer.ParseImageContainer(ffmContainer, file); } else { info.Metadata[Editions.DEFAULT_EDITION].VideoContainerType = FFMpegParseVideoContainer.ParseVideoContainer(ffmContainer, file); info.Metadata[Editions.DEFAULT_EDITION].AudioContainerType = FFMpegParseAudioContainer.ParseAudioContainer(ffmContainer, file); info.Metadata[Editions.DEFAULT_EDITION].ImageContainerType = FFMpegParseImageContainer.ParseImageContainer(ffmContainer, file); } }
internal static void ParseStreamVideoLine(IResourceAccessor file, string streamVideoLine, ref MetadataContainer info, Dictionary <string, CultureInfo> countryCodesMapping) { if (info.Video[Editions.DEFAULT_EDITION].Codec != VideoCodec.Unknown) { return; } streamVideoLine = streamVideoLine.Trim(); string beforeVideo = streamVideoLine.Substring(0, streamVideoLine.IndexOf("Video:", StringComparison.InvariantCultureIgnoreCase)); string afterVideo = streamVideoLine.Substring(beforeVideo.Length); string[] beforeVideoTokens = beforeVideo.Split(','); string[] afterVideoTokens = afterVideo.Split(','); foreach (string mediaToken in beforeVideoTokens) { string token = mediaToken.Trim(); if (token.StartsWith("Stream", StringComparison.InvariantCultureIgnoreCase)) { Match match = Regex.Match(token, @"#[\d][\.:](?<stream>[\d]{1,2}).*\((?<lang>(\w+))\)[\.:]", RegexOptions.IgnoreCase); if (match.Success) { info.Video[Editions.DEFAULT_EDITION].StreamIndex = Convert.ToInt32(match.Groups["stream"].Value.Trim()); if (match.Groups.Count == 4) { string lang = match.Groups["lang"].Value.Trim().ToUpperInvariant(); if (countryCodesMapping.ContainsKey(lang)) { info.Video[Editions.DEFAULT_EDITION].Language = countryCodesMapping[lang].TwoLetterISOLanguageName.ToUpperInvariant(); } } } else { match = Regex.Match(token, @"#[\d][\.:](?<stream>[\d]{1,2}).*[\.:]", RegexOptions.IgnoreCase); if (match.Success) { info.Video[Editions.DEFAULT_EDITION].StreamIndex = Convert.ToInt32(match.Groups["stream"].Value.Trim()); } } } } bool nextTokenIsPixelFormat = false; foreach (string mediaToken in afterVideoTokens) { string token = mediaToken.Trim(); if (token.StartsWith("Video:", StringComparison.InvariantCultureIgnoreCase)) { string[] parts = token.Substring(token.IndexOf("Video: ", StringComparison.InvariantCultureIgnoreCase) + 7).Split(' '); string codecValue = parts[0]; if ((codecValue != null) && (codecValue.StartsWith("drm", StringComparison.InvariantCultureIgnoreCase))) { throw new Exception($"MediaAnalyzer: {file} is DRM protected"); } string codecDetails = null; if (parts.Length > 1) { string details = string.Join(" ", parts).Trim(); if (details.Contains("(")) { int iIndex = details.IndexOf("("); codecDetails = details.Substring(iIndex + 1, details.IndexOf(")") - iIndex - 1); } } info.Video[Editions.DEFAULT_EDITION].Codec = FFMpegParseVideoCodec.ParseVideoCodec(codecValue); if (info.IsImage(Editions.DEFAULT_EDITION)) { info.Metadata[Editions.DEFAULT_EDITION].ImageContainerType = FFMpegParseImageContainer.ParseImageContainer(codecValue, file as ILocalFsResourceAccessor); } if (info.Video[Editions.DEFAULT_EDITION].Codec == VideoCodec.H264 || info.Video[Editions.DEFAULT_EDITION].Codec == VideoCodec.H265) { info.Video[Editions.DEFAULT_EDITION].ProfileType = FFMpegParseProfile.ParseProfile(codecDetails); } string fourCC = token.Trim(); if (token.Contains("(")) { string fourCCBlock = fourCC.Substring(fourCC.LastIndexOf("(") + 1, fourCC.LastIndexOf(")") - fourCC.LastIndexOf("(") - 1); if (fourCCBlock.IndexOf("/") > -1) { fourCC = (fourCCBlock.Split('/')[0].Trim()).ToLowerInvariant(); if (fourCC.IndexOf("[") == -1) { info.Video[Editions.DEFAULT_EDITION].FourCC = fourCC; } } } nextTokenIsPixelFormat = true; } else if (nextTokenIsPixelFormat) { nextTokenIsPixelFormat = false; if (info.IsImage(Editions.DEFAULT_EDITION)) { info.Image[Editions.DEFAULT_EDITION].PixelFormatType = FFMpegParsePixelFormat.ParsePixelFormat(token.Trim()); } else { info.Video[Editions.DEFAULT_EDITION].PixelFormatType = FFMpegParsePixelFormat.ParsePixelFormat(token.Trim()); } } else if (token.IndexOf("x", StringComparison.InvariantCultureIgnoreCase) > -1 && token.Contains("max") == false) { string resolution = token.Trim(); int aspectStart = resolution.IndexOf(" ["); if (aspectStart > -1) { info.Video[Editions.DEFAULT_EDITION].PixelAspectRatio = 1.0F; string aspectDef = resolution.Substring(aspectStart + 2, resolution.IndexOf("]") - aspectStart - 2); int sarIndex = aspectDef.IndexOf("SAR"); //Sample AR if (sarIndex < 0) { sarIndex = aspectDef.IndexOf("PAR"); //Pixel AR } if (sarIndex > -1) { aspectDef = aspectDef.Substring(sarIndex + 4); string sar = aspectDef.Substring(0, aspectDef.IndexOf(" ")).Trim(); string[] sarRatio = sar.Split(':'); if (sarRatio.Length == 2) { try { info.Video[Editions.DEFAULT_EDITION].PixelAspectRatio = Convert.ToSingle(sarRatio[0], CultureInfo.InvariantCulture) / Convert.ToSingle(sarRatio[1], CultureInfo.InvariantCulture); } catch { } } } resolution = resolution.Substring(0, aspectStart); } string[] res = resolution.Split('x'); if (res.Length == 2 && res[0].All(Char.IsDigit) && res[1].All(Char.IsDigit)) { try { if (info.IsImage(Editions.DEFAULT_EDITION)) { info.Image[Editions.DEFAULT_EDITION].Width = Convert.ToInt32(res[0], CultureInfo.InvariantCulture); info.Image[Editions.DEFAULT_EDITION].Height = Convert.ToInt32(res[1], CultureInfo.InvariantCulture); } else { info.Video[Editions.DEFAULT_EDITION].Width = Convert.ToInt32(res[0], CultureInfo.InvariantCulture); info.Video[Editions.DEFAULT_EDITION].Height = Convert.ToInt32(res[1], CultureInfo.InvariantCulture); } } catch { } if (info.Video[Editions.DEFAULT_EDITION].Height > 0) { info.Video[Editions.DEFAULT_EDITION].AspectRatio = (float)info.Video[Editions.DEFAULT_EDITION].Width / (float)info.Video[Editions.DEFAULT_EDITION].Height; } } } else if (token.IndexOf("SAR", StringComparison.InvariantCultureIgnoreCase) > -1 || token.IndexOf("PAR", StringComparison.InvariantCultureIgnoreCase) > -1) { info.Video[Editions.DEFAULT_EDITION].PixelAspectRatio = 1.0F; string aspectDef = token.Trim(); int sarIndex = aspectDef.IndexOf("SAR", StringComparison.InvariantCultureIgnoreCase); //Sample AR if (sarIndex < 0) { sarIndex = aspectDef.IndexOf("PAR", StringComparison.InvariantCultureIgnoreCase); //Pixel AR } if (sarIndex > -1) { aspectDef = aspectDef.Substring(sarIndex + 4); string sar = aspectDef.Substring(0, aspectDef.IndexOf(" ")).Trim(); string[] sarRatio = sar.Split(':'); if (sarRatio.Length == 2) { try { info.Video[Editions.DEFAULT_EDITION].PixelAspectRatio = Convert.ToSingle(sarRatio[0], CultureInfo.InvariantCulture) / Convert.ToSingle(sarRatio[1], CultureInfo.InvariantCulture); } catch { } } } } else if (token.IndexOf("kb/s", StringComparison.InvariantCultureIgnoreCase) > -1) { string[] parts = token.Split(' '); //if (parts.Length == 3 && parts[1].All(Char.IsDigit)) // info.Video.Bitrate = long.Parse(parts[1].Trim(), CultureInfo.InvariantCulture); if (parts.Length == 2 && parts[0].All(Char.IsDigit)) { info.Video[Editions.DEFAULT_EDITION].Bitrate = long.Parse(parts[0].Trim(), CultureInfo.InvariantCulture); } } else if (token.IndexOf("mb/s", StringComparison.InvariantCultureIgnoreCase) > -1) { string[] parts = token.Split(' '); //if (parts.Length == 3 && parts[1].All(Char.IsDigit)) // info.Video.Bitrate = long.Parse(parts[1].Trim(), CultureInfo.InvariantCulture) * 1024; if (parts.Length == 2 && parts[0].All(Char.IsDigit)) { info.Video[Editions.DEFAULT_EDITION].Bitrate = long.Parse(parts[0].Trim(), CultureInfo.InvariantCulture) * 1024; } } else if (token.IndexOf("tbr", StringComparison.InvariantCultureIgnoreCase) > -1 || token.IndexOf("fps", StringComparison.InvariantCultureIgnoreCase) > -1) { if (info.Video[Editions.DEFAULT_EDITION].Framerate == 0) { string fpsValue = "23.976"; if (token.IndexOf("tbr", StringComparison.InvariantCultureIgnoreCase) > -1) { fpsValue = token.Substring(0, token.IndexOf("tbr", StringComparison.InvariantCultureIgnoreCase)).Trim(); } else if (token.IndexOf("fps", StringComparison.InvariantCultureIgnoreCase) > -1) { fpsValue = token.Substring(0, token.IndexOf("fps", StringComparison.InvariantCultureIgnoreCase)).Trim(); } if (fpsValue.Contains("k")) { fpsValue = fpsValue.Replace("k", "000"); } double fr = 0; float validFrameRate = 23.976F; if (double.TryParse(fpsValue, out fr) == true) { if (fr > 23.899999999999999D && fr < 23.989999999999998D) { validFrameRate = 23.976F; } else if (fr > 23.989999999999998D && fr < 24.100000000000001D) { validFrameRate = 24; } else if (fr >= 24.989999999999998D && fr < 25.100000000000001D) { validFrameRate = 25; } else if (fr > 29.899999999999999D && fr < 29.989999999999998D) { validFrameRate = 29.97F; } else if (fr >= 29.989999999999998D && fr < 30.100000000000001D) { validFrameRate = 30; } else if (fr > 49.899999999999999D && fr < 50.100000000000001D) { validFrameRate = 50; } else if (fr > 59.899999999999999D && fr < 59.990000000000002D) { validFrameRate = 59.94F; } else if (fr >= 59.990000000000002D && fr < 60.100000000000001D) { validFrameRate = 60; } } info.Video[Editions.DEFAULT_EDITION].Framerate = validFrameRate; } } } }