public async Task <MetadataContainer> ParseMediaItemAsync(MediaItem media, int?editionId = null, bool cache = true) { try { if (media.IsStub) { return(null); } string category = null; MetadataContainer info = null; //Check for live items if (media.Aspects.ContainsKey(AudioAspect.ASPECT_ID)) { category = AUDIO_CATEGORY; if (media.IsLiveRadioItem() && media is LiveTvMediaItem ltmi) { info = await ParseSlimTvItemAsync(ltmi).ConfigureAwait(false); if (info != null) { info.Metadata[Editions.DEFAULT_EDITION].Live = true; info.Metadata[Editions.DEFAULT_EDITION].Size = 0; } return(info); } } else if (media.Aspects.ContainsKey(VideoAspect.ASPECT_ID)) { category = VIDEO_CATEGORY; if (media.IsLiveTvItem() && media is LiveTvMediaItem ltmi) { info = await ParseSlimTvItemAsync(ltmi).ConfigureAwait(false); if (info != null) { info.Metadata[Editions.DEFAULT_EDITION].Live = true; info.Metadata[Editions.DEFAULT_EDITION].Size = 0; } return(info); } } else if (media.Aspects.ContainsKey(ImageAspect.ASPECT_ID)) { category = IMAGE_CATEGORY; } info = await LoadAnalysisAsync(media, category, media.MediaItemId); if (info != null) { return(info); } IList <MultipleMediaItemAspect> providerAspects; if (!MediaItemAspect.TryGetAspects(media.Aspects, ProviderResourceAspect.Metadata, out providerAspects)) { return(null); } IDictionary <int, ResourceLocator> resources = null; if (media.HasEditions) { IEnumerable <int> praIdxs = null; if (editionId.HasValue) { praIdxs = media.Editions.First(e => e.Key == editionId.Value).Value.PrimaryResourceIndexes; } else { praIdxs = media.Editions.SelectMany(e => e.Value.PrimaryResourceIndexes).Distinct(); } resources = providerAspects.Where(pra => praIdxs.Contains(pra.GetAttributeValue <int>(ProviderResourceAspect.ATTR_RESOURCE_INDEX))). ToDictionary(pra => pra.GetAttributeValue <int>(ProviderResourceAspect.ATTR_RESOURCE_INDEX), pra => new ResourceLocator(pra.GetAttributeValue <string>(ProviderResourceAspect.ATTR_SYSTEM_ID), ResourcePath.Deserialize(pra.GetAttributeValue <string>(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH)))); } else { resources = providerAspects.Where(pra => pra.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_PRIMARY). ToDictionary(pra => pra.GetAttributeValue <int>(ProviderResourceAspect.ATTR_RESOURCE_INDEX), pra => new ResourceLocator(pra.GetAttributeValue <string>(ProviderResourceAspect.ATTR_SYSTEM_ID), ResourcePath.Deserialize(pra.GetAttributeValue <string>(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH)))); } //Process media resources Dictionary <int, Dictionary <int, IResourceAccessor> > editions = new Dictionary <int, Dictionary <int, IResourceAccessor> >(); foreach (var res in resources) { int edition = Editions.DEFAULT_EDITION; if (media.HasEditions) { edition = media.Editions.FirstOrDefault(e => e.Value.PrimaryResourceIndexes.Contains(res.Key)).Value.SetNo; } if (!editions.ContainsKey(edition)) { editions.Add(edition, new Dictionary <int, IResourceAccessor>()); } IResourceAccessor mia = res.Value.CreateAccessor(); if (mia is IFileSystemResourceAccessor fileRes && !fileRes.IsFile) { if (fileRes.ResourceExists("VIDEO_TS")) { using (IFileSystemResourceAccessor fsraVideoTs = fileRes.GetResource("VIDEO_TS")) { if (fsraVideoTs != null && fsraVideoTs.ResourceExists("VIDEO_TS.IFO")) { //Find all titles and add each of them var titles = GetDvdTitleFiles(fsraVideoTs); foreach (var title in titles) { int fileNo = 0; foreach (var file in title.Value) { fileNo++; int titleKey = MetadataContainer.GetDvdResource(res.Key, title.Key, fileNo); editions[edition].Add(titleKey, file); } } } } } else if (fileRes.ResourceExists("BDMV")) { using (IFileSystemResourceAccessor fsraBDMV = fileRes.GetResource("BDMV")) { if (fsraBDMV != null && fsraBDMV.ResourceExists("index.bdmv") && fsraBDMV.ResourceExists("STREAM")) { using (IFileSystemResourceAccessor fsraStream = fsraBDMV.GetResource("STREAM")) { var orderedFileList = fsraStream.GetFiles().Where(f => f.ResourceName.EndsWith(".m2ts", StringComparison.InvariantCultureIgnoreCase)).OrderByDescending(f => f.Size); //Use the largest file which is probably the main stream var mainStream = orderedFileList.First(); editions[edition].Add(res.Key, mainStream); } } } } } else { editions[edition].Add(res.Key, mia); } mia.Dispose(); }