public virtual Task <bool> TryExtractMetadataAsync(IResourceAccessor mediaItemAccessor, IDictionary <Guid, IList <MediaItemAspect> > extractedAspectData, bool forceQuickMode)
        {
            try
            {
                IResourceAccessor metaFileAccessor;
                if (!CanExtract(mediaItemAccessor, extractedAspectData, out metaFileAccessor))
                {
                    return(Task.FromResult(false));
                }

                Argus.Recording recording;
                using (metaFileAccessor)
                {
                    using (Stream metaStream = ((IFileSystemResourceAccessor)metaFileAccessor).OpenRead())
                        recording = (Argus.Recording)GetTagsXmlSerializer().Deserialize(metaStream);
                }

                // Force MimeType
                IList <MultipleMediaItemAspect> providerAspects;
                MediaItemAspect.TryGetAspects(extractedAspectData, ProviderResourceAspect.Metadata, out providerAspects);
                foreach (MultipleMediaItemAspect aspect in providerAspects)
                {
                    aspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, "slimtv/arg");
                }

                MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_ISVIRTUAL, false);
                MediaItemAspect.SetAttribute(extractedAspectData, VideoAspect.ATTR_ISDVD, false);

                MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, recording.Title);
                MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_SORT_TITLE, BaseInfo.GetSortTitle(recording.Title));

                if (!string.IsNullOrEmpty(recording.Category?.Trim()))
                {
                    List <GenreInfo> genreList = new List <GenreInfo>(new GenreInfo[] { new GenreInfo {
                                                                                            Name = recording.Category.Trim()
                                                                                        } });
                    IGenreConverter converter = ServiceRegistration.Get <IGenreConverter>();
                    foreach (var genre in genreList)
                    {
                        if (!genre.Id.HasValue && converter.GetGenreId(genre.Name, GenreCategory.Movie, null, out int genreId))
                        {
                            genre.Id = genreId;
                        }
                    }
                    if (genreList.Count > 0)
                    {
                        MultipleMediaItemAspect genreAspect = MediaItemAspect.CreateAspect(extractedAspectData, GenreAspect.Metadata);
                        genreAspect.SetAttribute(GenreAspect.ATTR_ID, genreList[0].Id);
                        genreAspect.SetAttribute(GenreAspect.ATTR_GENRE, genreList[0].Name);
                    }
                }

                MediaItemAspect.SetAttribute(extractedAspectData, VideoAspect.ATTR_STORYPLOT, recording.Description);

                Match yearMatch = _yearMatcher.Match(recording.Description);
                int   guessedYear;
                if (int.TryParse(yearMatch.Value, out guessedYear))
                {
                    MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, new DateTime(guessedYear, 1, 1));
                }

                MediaItemAspect.SetAttribute(extractedAspectData, RecordingAspect.ATTR_CHANNEL, recording.ChannelDisplayName);

                MediaItemAspect.SetAttribute(extractedAspectData, RecordingAspect.ATTR_STARTTIME, recording.ProgramStartTime);

                MediaItemAspect.SetAttribute(extractedAspectData, RecordingAspect.ATTR_ENDTIME, recording.ProgramStopTime);
                RecordingUtils.CheckAndPrepareAspectRefresh(extractedAspectData);

                if (!string.IsNullOrWhiteSpace(recording.Director))
                {
                    MediaItemAspect.SetCollectionAttribute(extractedAspectData, VideoAspect.ATTR_DIRECTORS, recording.Director.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
                }

                if (!string.IsNullOrWhiteSpace(recording.Actors))
                {
                    MediaItemAspect.SetCollectionAttribute(extractedAspectData, VideoAspect.ATTR_ACTORS, recording.Actors.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
                }

                return(Task.FromResult(true));
            }
            catch (Exception e)
            {
                // Only log at the info level here - And simply return false. This lets the caller know that we
                // couldn't perform our task here.
                ServiceRegistration.Get <ILogger>().Info("ArgusRecordingMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message);
            }
            return(Task.FromResult(false));
        }
예제 #2
0
        public virtual Task <bool> TryExtractMetadataAsync(IResourceAccessor mediaItemAccessor, IDictionary <Guid, IList <MediaItemAspect> > extractedAspectData, bool forceQuickMode)
        {
            try
            {
                IResourceAccessor metaFileAccessor;
                if (!CanExtract(mediaItemAccessor, extractedAspectData, out metaFileAccessor))
                {
                    return(Task.FromResult(false));
                }

                Tags tags;
                using (metaFileAccessor)
                {
                    using (Stream metaStream = ((IFileSystemResourceAccessor)metaFileAccessor).OpenRead())
                        tags = (Tags)GetTagsXmlSerializer().Deserialize(metaStream);
                }

                //Assign all tags to the aspects for both tv and radio recordings
                string value;
                MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_ISVIRTUAL, false);
                if (TryGet(tags, TAG_TITLE, out value) && !string.IsNullOrEmpty(value))
                {
                    if (value.Equals("manual", StringComparison.InvariantCultureIgnoreCase))
                    {
                        value = ResourcePathHelper.GetFileNameWithoutExtension(metaFileAccessor.Path);
                    }

                    MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, value);
                    MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_SORT_TITLE, BaseInfo.GetSortTitle(value));
                }

                if (TryGet(tags, TAG_CHANNEL, out value))
                {
                    MediaItemAspect.SetAttribute(extractedAspectData, RecordingAspect.ATTR_CHANNEL, value);
                }

                // Recording date formatted: 2011-11-04 20:55
                DateTime tmpValue;
                DateTime?recordingStart = null;
                DateTime?recordingEnd   = null;
                DateTime?programStart   = null;
                DateTime?programEnd     = null;

                // First try to read program start and end times, they will be preferred.
                if (TryGet(tags, TAG_PROGRAMSTARTTIME, out value) && DateTime.TryParse(value, out tmpValue))
                {
                    programStart = tmpValue;
                }

                if (TryGet(tags, TAG_PROGRAMENDTIME, out value) && DateTime.TryParse(value, out tmpValue))
                {
                    programEnd = tmpValue;
                }

                if (TryGet(tags, TAG_STARTTIME, out value) && DateTime.TryParse(value, out tmpValue))
                {
                    recordingStart = tmpValue;
                }

                if (TryGet(tags, TAG_ENDTIME, out value) && DateTime.TryParse(value, out tmpValue))
                {
                    recordingEnd = tmpValue;
                }

                // Correct start time if recording started before the program (skip pre-recording offset)
                if (programStart.HasValue && recordingStart.HasValue && programStart > recordingStart)
                {
                    recordingStart = programStart;
                }

                // Correct end time if recording ended after the program (skip the post-recording offset)
                if (programEnd.HasValue && recordingEnd.HasValue && programEnd < recordingEnd)
                {
                    recordingEnd = programEnd;
                }

                if (recordingStart.HasValue)
                {
                    MediaItemAspect.SetAttribute(extractedAspectData, RecordingAspect.ATTR_STARTTIME, recordingStart.Value);
                }
                if (recordingEnd.HasValue)
                {
                    MediaItemAspect.SetAttribute(extractedAspectData, RecordingAspect.ATTR_ENDTIME, recordingEnd.Value);
                    RecordingUtils.CheckAndPrepareAspectRefresh(extractedAspectData);
                }

                if (extractedAspectData.ContainsKey(VideoAspect.ASPECT_ID)) //Only add video information for actual video recordings
                {
                    // Force MimeType
                    IList <MultipleMediaItemAspect> providerAspects;
                    MediaItemAspect.TryGetAspects(extractedAspectData, ProviderResourceAspect.Metadata, out providerAspects);
                    foreach (MultipleMediaItemAspect aspect in providerAspects)
                    {
                        aspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, "slimtv/video");
                    }

                    MediaItemAspect.SetAttribute(extractedAspectData, VideoAspect.ATTR_ISDVD, false);
                    if (TryGet(tags, TAG_PLOT, out value))
                    {
                        MediaItemAspect.SetAttribute(extractedAspectData, VideoAspect.ATTR_STORYPLOT, value);
                        Match yearMatch = _yearMatcher.Match(value);
                        int   guessedYear;
                        if (int.TryParse(yearMatch.Value, out guessedYear))
                        {
                            MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, new DateTime(guessedYear, 1, 1));
                        }
                    }
                    if (TryGet(tags, TAG_GENRE, out value) && !string.IsNullOrEmpty(value?.Trim()))
                    {
                        List <GenreInfo> genreList = new List <GenreInfo>(new GenreInfo[] { new GenreInfo {
                                                                                                Name = value.Trim()
                                                                                            } });
                        IGenreConverter converter = ServiceRegistration.Get <IGenreConverter>();
                        foreach (var genre in genreList)
                        {
                            if (!genre.Id.HasValue && converter.GetGenreId(genre.Name, GenreCategory.Movie, null, out int genreId))
                            {
                                genre.Id = genreId;
                            }
                        }
                        MultipleMediaItemAspect genreAspect = MediaItemAspect.CreateAspect(extractedAspectData, GenreAspect.Metadata);
                        genreAspect.SetAttribute(GenreAspect.ATTR_ID, genreList[0].Id);
                        genreAspect.SetAttribute(GenreAspect.ATTR_GENRE, genreList[0].Name);
                    }
                }
                else //Add comment for radio recordings
                {
                    if (TryGet(tags, TAG_PLOT, out value))
                    {
                        MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_COMMENT, value);
                    }
                    if (TryGet(tags, TAG_GENRE, out value) && !string.IsNullOrEmpty(value?.Trim()))
                    {
                        List <GenreInfo> genreList = new List <GenreInfo>(new GenreInfo[] { new GenreInfo {
                                                                                                Name = value.Trim()
                                                                                            } });
                        IGenreConverter converter = ServiceRegistration.Get <IGenreConverter>();
                        foreach (var genre in genreList)
                        {
                            if (!genre.Id.HasValue && converter.GetGenreId(genre.Name, GenreCategory.Music, null, out int genreId))
                            {
                                genre.Id = genreId;
                            }
                        }
                        MultipleMediaItemAspect genreAspect = MediaItemAspect.CreateAspect(extractedAspectData, GenreAspect.Metadata);
                        genreAspect.SetAttribute(GenreAspect.ATTR_ID, genreList[0].Id);
                        genreAspect.SetAttribute(GenreAspect.ATTR_GENRE, genreList[0].Name);
                    }
                }

                return(Task.FromResult(true));
            }
            catch (Exception e)
            {
                // Only log at the info level here - And simply return false. This lets the caller know that we
                // couldn't perform our task here.
                ServiceRegistration.Get <ILogger>().Info("Tve3RecordingMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", mediaItemAccessor.CanonicalLocalResourcePath, e.Message);
            }
            return(Task.FromResult(false));
        }