コード例 #1
0
    /// <summary>
    /// Creates a MediaItem that represents a TV stream. The MediaItem also holds information about stream indices to provide PiP
    /// functions (<paramref name="slotIndex"/>).
    /// </summary>
    /// <param name="slotIndex">Index of the slot (0/1)</param>
    /// <param name="path">Path or URL of the stream</param>
    /// <param name="channel"></param>
    /// <returns></returns>
    public static LiveTvMediaItem CreateMediaItem(int slotIndex, string path, IChannel channel)
    {
      if (!String.IsNullOrEmpty(path))
      {
        ISystemResolver systemResolver = ServiceRegistration.Get<ISystemResolver>();
        IDictionary<Guid, MediaItemAspect> aspects = new Dictionary<Guid, MediaItemAspect>();
        MediaItemAspect providerResourceAspect;
        MediaItemAspect mediaAspect;

        SlimTvResourceAccessor resourceAccessor = new SlimTvResourceAccessor(slotIndex, path);
        aspects[ProviderResourceAspect.ASPECT_ID] = providerResourceAspect = new MediaItemAspect(ProviderResourceAspect.Metadata);
        aspects[MediaAspect.ASPECT_ID] = mediaAspect = new MediaItemAspect(MediaAspect.Metadata);
        // VideoAspect needs to be included to associate VideoPlayer later!
        aspects[VideoAspect.ASPECT_ID] = new MediaItemAspect(VideoAspect.Metadata);
        providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_SYSTEM_ID, systemResolver.LocalSystemId);

        String raPath = resourceAccessor.CanonicalLocalResourcePath.Serialize();
        providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH, raPath);

        mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, "Live TV");
        mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, "video/livetv"); // Custom mimetype for LiveTv

        LiveTvMediaItem tvStream = new LiveTvMediaItem(new Guid(), aspects);

        tvStream.AdditionalProperties[LiveTvMediaItem.SLOT_INDEX] = slotIndex;
        tvStream.AdditionalProperties[LiveTvMediaItem.CHANNEL] = channel;
        tvStream.AdditionalProperties[LiveTvMediaItem.TUNING_TIME] = DateTime.Now;
        return tvStream;
      }
      return null;
    }
コード例 #2
0
        /// <summary>
        /// Constructs a dynamic <see cref="MediaItem"/> that contains the URL for the given <paramref name="trailer"/>.
        /// </summary>
        /// <param name="trailer">Trailer.</param>
        private static MediaItem CreateStreamMediaItem(Trailer trailer)
        {
            IDictionary<Guid, MediaItemAspect> aspects = new Dictionary<Guid, MediaItemAspect>();

              MediaItemAspect providerResourceAspect;
              aspects[ProviderResourceAspect.ASPECT_ID] = providerResourceAspect = new MediaItemAspect(ProviderResourceAspect.Metadata);
              MediaItemAspect mediaAspect;
              aspects[MediaAspect.ASPECT_ID] = mediaAspect = new MediaItemAspect(MediaAspect.Metadata);
              aspects[VideoAspect.ASPECT_ID] = new MediaItemAspect(VideoAspect.Metadata); // VideoAspect needs to be contained for player mapping

              providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH, RawUrlResourceProvider.ToProviderResourcePath(trailer.Url).Serialize());
              providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_SYSTEM_ID, ServiceRegistration.Get<ISystemResolver>().LocalSystemId);

              mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, CINEMA_MIMETYPE);
              mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, trailer.Title);

              var mediaItem = new MediaItem(Guid.Empty, aspects);
              return mediaItem;
        }
コード例 #3
0
    private static LiveTvMediaItem.LiveTvMediaItem CreateCommonMediaItem(int slotIndex, string path, bool isTv)
    {
      ISystemResolver systemResolver = ServiceRegistration.Get<ISystemResolver>();
      IDictionary<Guid, MediaItemAspect> aspects = new Dictionary<Guid, MediaItemAspect>();
      MediaItemAspect providerResourceAspect;
      MediaItemAspect mediaAspect;

      SlimTvResourceAccessor resourceAccessor = new SlimTvResourceAccessor(slotIndex, path);
      aspects[ProviderResourceAspect.ASPECT_ID] = providerResourceAspect = new MediaItemAspect(ProviderResourceAspect.Metadata);
      aspects[MediaAspect.ASPECT_ID] = mediaAspect = new MediaItemAspect(MediaAspect.Metadata);
      providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_SYSTEM_ID, systemResolver.LocalSystemId);

      String raPath = resourceAccessor.CanonicalLocalResourcePath.Serialize();
      providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH, raPath);

      string title;
      string mimeType;
      if (isTv)
      {
        // VideoAspect needs to be included to associate VideoPlayer later!
        aspects[VideoAspect.ASPECT_ID] = new MediaItemAspect(VideoAspect.Metadata);
        title = "Live TV";
        mimeType = LiveTvMediaItem.LiveTvMediaItem.MIME_TYPE_TV;
      }
      else
      {
        // AudioAspect needs to be included to associate an AudioPlayer later!
        aspects[AudioAspect.ASPECT_ID] = new MediaItemAspect(AudioAspect.Metadata);
        title = "Live Radio";
        mimeType = LiveTvMediaItem.LiveTvMediaItem.MIME_TYPE_RADIO;
      }
      mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, title);
      mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, mimeType); // Custom mimetype for LiveTv or Radio
      LiveTvMediaItem.LiveTvMediaItem tvStream = new LiveTvMediaItem.LiveTvMediaItem(new Guid(), aspects);
      return tvStream;
    }
コード例 #4
0
ファイル: StubParser.cs プロジェクト: zeroxist/MediaPortal-2
        public static void ParseFileInfo(IDictionary <Guid, IList <MediaItemAspect> > extractedAspectData, HashSet <StreamDetailsStub> FileInfo, string title, decimal?fps = null)
        {
            int streamId = 0;

            if (FileInfo != null && FileInfo.Count > 0)
            {
                if (FileInfo.First().VideoStreams != null && FileInfo.First().VideoStreams.Count > 0)
                {
                    foreach (var video in FileInfo.First().VideoStreams)
                    {
                        MultipleMediaItemAspect videoStreamAspects = MediaItemAspect.CreateAspect(extractedAspectData, VideoStreamAspect.Metadata);
                        videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_RESOURCE_INDEX, 0);
                        videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_STREAM_INDEX, streamId++);

                        string videoType = VideoStreamAspect.GetVideoType(null, video.StereoMode, video.Height, video.Width);
                        if (!string.IsNullOrEmpty(videoType))
                        {
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_TYPE, videoType);
                        }
                        if (videoType == VideoStreamAspect.TYPE_SBS || videoType == VideoStreamAspect.TYPE_HSBS)
                        {
                            video.Width  = video.Width.Value / 2;
                            video.Aspect = (decimal)video.Width.Value / (decimal)video.Height.Value;
                        }
                        else if (videoType == VideoStreamAspect.TYPE_TAB || videoType == VideoStreamAspect.TYPE_HTAB)
                        {
                            video.Height = video.Height.Value / 2;
                            video.Aspect = (decimal)video.Width.Value / (decimal)video.Height.Value;
                        }

                        if (video.Aspect.HasValue)
                        {
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_ASPECTRATIO, Convert.ToSingle(video.Aspect.Value));
                        }
                        if (fps.HasValue)
                        {
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_FPS, Convert.ToSingle(fps.Value));
                        }
                        if (video.Width.HasValue)
                        {
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_WIDTH, video.Width.Value);
                        }
                        if (video.Height.HasValue)
                        {
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_HEIGHT, video.Height.Value);
                        }
                        if (video.Duration.HasValue)
                        {
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_DURATION, Convert.ToInt64(video.Duration.Value.TotalSeconds));
                        }
                        if (video.Bitrate.HasValue)
                        {
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEOBITRATE, video.Bitrate.Value / 1000); // We store kbit/s
                        }
                        videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEOENCODING, video.Codec);
                        if (FileInfo.First().AudioStreams != null && FileInfo.First().AudioStreams.Count > 0)
                        {
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_AUDIOSTREAMCOUNT, FileInfo.First().AudioStreams.Count);
                        }
                        videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART, -1);
                        videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART_SET, -1);

                        List <string> suffixes = new List <string>();
                        if (!string.IsNullOrEmpty(videoType))
                        {
                            suffixes.Add(videoType);
                        }
                        if (video.Height.HasValue && video.Width.HasValue)
                        {
                            suffixes.Add($"{video.Width.Value}x{video.Height.Value}");
                        }
                        videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART_SET_NAME, title + (suffixes.Count > 0 ? " (" + string.Join(", ", suffixes) + ")" : ""));
                    }
                }

                if (FileInfo.First().AudioStreams != null && FileInfo.First().AudioStreams.Count > 0)
                {
                    foreach (var audio in FileInfo.First().AudioStreams)
                    {
                        MultipleMediaItemAspect audioAspect = MediaItemAspect.CreateAspect(extractedAspectData, VideoAudioStreamAspect.Metadata);
                        audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_RESOURCE_INDEX, 0);
                        audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_STREAM_INDEX, streamId++);
                        if (audio.Codec != null)
                        {
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOENCODING, audio.Codec);
                        }
                        if (audio.Bitrate != null)
                        {
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOBITRATE, audio.Bitrate.Value / 1000); // We store kbit/s
                        }
                        if (audio.Channels != null)
                        {
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOCHANNELS, audio.Channels.Value);
                        }
                        if (audio.Language != null)
                        {
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOLANGUAGE, ParseLanguage(audio.Language));
                        }
                    }
                }

                if (FileInfo.First().SubtitleStreams != null && FileInfo.First().SubtitleStreams.Count > 0)
                {
                    foreach (var subtitle in FileInfo.First().SubtitleStreams)
                    {
                        MultipleMediaItemAspect subtitleAspect = MediaItemAspect.CreateAspect(extractedAspectData, SubtitleAspect.Metadata);
                        subtitleAspect.SetAttribute(SubtitleAspect.ATTR_RESOURCE_INDEX, 0);
                        subtitleAspect.SetAttribute(SubtitleAspect.ATTR_VIDEO_RESOURCE_INDEX, 0);
                        subtitleAspect.SetAttribute(SubtitleAspect.ATTR_STREAM_INDEX, streamId++);
                        subtitleAspect.SetAttribute(SubtitleAspect.ATTR_INTERNAL, true);
                        if (subtitle.Language != null)
                        {
                            subtitleAspect.SetAttribute(SubtitleAspect.ATTR_SUBTITLE_LANGUAGE, ParseLanguage(subtitle.Language));
                        }
                    }
                }
            }
        }
コード例 #5
0
        public override int Compare(MediaItem x, MediaItem y)
        {
            SingleMediaItemAspect mediaAspectX;
            SingleMediaItemAspect mediaAspectY;

            if (MediaItemAspect.TryGetAspect(x.Aspects, MediaAspect.Metadata, out mediaAspectX) && MediaItemAspect.TryGetAspect(y.Aspects, MediaAspect.Metadata, out mediaAspectY))
            {
                DateTime?recordingTimeX = (DateTime?)mediaAspectX.GetAttributeValue(MediaAspect.ATTR_RECORDINGTIME);
                DateTime?recordingTimeY = (DateTime?)mediaAspectY.GetAttributeValue(MediaAspect.ATTR_RECORDINGTIME);
                return(ObjectUtils.Compare(recordingTimeX, recordingTimeY));
            }
            return(base.Compare(x, y));
        }
コード例 #6
0
 /// <summary>
 /// Adds a direcotry MediaItem to the MediaLibrary
 /// </summary>
 /// <param name="directoryAccessor">ResourceAccessor to the directory to be saved</param>
 /// <param name="parentDirectoryId">ID of the parent Directory</param>
 /// <returns></returns>
 private async Task<Guid> AddDirectory(IFileSystemResourceAccessor directoryAccessor, Guid parentDirectoryId)
 {
   var directoryPath = directoryAccessor.CanonicalLocalResourcePath;
   var mediaAspect = new MediaItemAspect(MediaAspect.Metadata);
   mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, directoryAccessor.ResourceName);
   mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, null);
   mediaAspect.SetAttribute(MediaAspect.ATTR_RECORDINGTIME, DateTime.MinValue);
   mediaAspect.SetAttribute(MediaAspect.ATTR_RATING, 0);
   mediaAspect.SetAttribute(MediaAspect.ATTR_COMMENT, null);
   mediaAspect.SetAttribute(MediaAspect.ATTR_LASTPLAYED, DateTime.MinValue);
   var directoryAspect = new MediaItemAspect(DirectoryAspect.Metadata);
   IList<MediaItemAspect> aspects = new List<MediaItemAspect>(new[]
     {
         mediaAspect,
         directoryAspect
     });
   return await UpdateMediaItem(parentDirectoryId, directoryPath, aspects);
 }
コード例 #7
0
ファイル: TraktHandler.cs プロジェクト: nagyist/MediaPortal-2
        private int GetSeasonIndex(MediaItem currMediaItem)
        {
            int value;

            return(MediaItemAspect.TryGetAttribute(currMediaItem.Aspects, SeriesAspect.ATTR_SEASON, out value) ? value : 0);
        }
コード例 #8
0
ファイル: TraktHandler.cs プロジェクト: nagyist/MediaPortal-2
        private string GetMovieTitle(MediaItem currMediaItem)
        {
            string value;

            return(MediaItemAspect.TryGetAttribute(currMediaItem.Aspects, MovieAspect.ATTR_MOVIE_NAME, out value) ? value : null);
        }
コード例 #9
0
        /// <summary>
        /// Creates Scrobble data based on a DBMovieInfo object
        /// </summary>
        /// <param name="psc"></param>
        /// <param name="pc">PlayerContext</param>
        /// <param name="starting"></param>
        /// <param name="scrobbleData"></param>
        /// <param name="state"></param>
        /// <returns>The Trakt scrobble data to send</returns>
        private bool TryCreateScrobbleData(IPlayerSlotController psc, IPlayerContext pc, bool starting, out AbstractScrobble scrobbleData, out TraktScrobbleStates state)
        {
            scrobbleData = null;
            state        = starting ? TraktScrobbleStates.watching : TraktScrobbleStates.scrobble;
            if (_settings.Settings.Authentication == null)
            {
                return(false);
            }

            string username = _settings.Settings.Authentication.Username;
            string password = _settings.Settings.Authentication.Password;

            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            {
                return(false);
            }

            // For canceling the watching, it is to have no TraktMovieScrobble.
            if (pc.CurrentMediaItem == null)
            {
                if (starting)
                {
                    return(false);
                }
                state = TraktScrobbleStates.cancelwatching;
                return(true);
            }

            bool isMovie  = pc.CurrentMediaItem.Aspects.ContainsKey(MovieAspect.ASPECT_ID);
            bool isSeries = pc.CurrentMediaItem.Aspects.ContainsKey(SeriesAspect.ASPECT_ID);

            if (!isMovie && !isSeries)
            {
                return(false);
            }

            string title = pc.CurrentPlayer != null ? pc.CurrentPlayer.MediaItemTitle : null;
            IMediaPlaybackControl pmc = pc.CurrentPlayer as IMediaPlaybackControl;
            TimeSpan currentPosition;

            if (pmc != null)
            {
                _progressUpdateWorks[psc].Duration = pmc.Duration;
                currentPosition = pmc.CurrentTime;
            }
            else
            {
                // Player is already removed on stopping, so take the resume position if available
                currentPosition = _progressUpdateWorks[psc].ResumePosition;
            }

            int progress = currentPosition == TimeSpan.Zero ? (starting ? 0 : 100) : Math.Min((int)(currentPosition.TotalSeconds * 100 / _progressUpdateWorks[psc].Duration.TotalSeconds), 100);

            string   value;
            int      iValue;
            DateTime dtValue;
            long     lValue;

            if (isMovie)
            {
                TraktMovieScrobble movie = new TraktMovieScrobble();
                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MovieAspect.ATTR_IMDB_ID, out value) && !string.IsNullOrWhiteSpace(value))
                {
                    movie.IMDBID = value;
                }

                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MovieAspect.ATTR_TMDB_ID, out iValue) && iValue > 0)
                {
                    movie.TMDBID = iValue.ToString();
                }

                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MediaAspect.ATTR_RECORDINGTIME, out dtValue))
                {
                    movie.Year = dtValue.Year.ToString();
                }

                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MovieAspect.ATTR_RUNTIME_M, out iValue) && iValue > 0)
                {
                    movie.Duration = iValue.ToString();
                }

                scrobbleData = movie;
            }
            if (isSeries)
            {
                TraktEpisodeScrobble series = new TraktEpisodeScrobble();
                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_IMDB_ID, out value) && !string.IsNullOrWhiteSpace(value))
                {
                    series.IMDBID = value;
                }

                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_TVDB_ID, out iValue))
                {
                    series.SeriesID = iValue.ToString();
                }

                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_SERIESNAME, out value) && !string.IsNullOrWhiteSpace(value))
                {
                    series.Title = value;
                }

                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_FIRSTAIRED, out dtValue))
                {
                    series.Year = dtValue.Year.ToString();
                }

                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_SEASON, out iValue))
                {
                    series.Season = iValue.ToString();
                }
                List <int> intList;
                if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_EPISODE, out intList) && intList.Any())
                {
                    series.Episode = intList.First().ToString(); // TODO: multi episode files?!
                }
                scrobbleData = series;
            }

            // Fallback duration info
            if (string.IsNullOrWhiteSpace(scrobbleData.Duration) && MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, VideoAspect.ATTR_DURATION, out lValue) && lValue > 0)
            {
                scrobbleData.Duration = (lValue / 60).ToString();
            }

            if (string.IsNullOrWhiteSpace(scrobbleData.Title))
            {
                scrobbleData.Title = title;
            }

            scrobbleData.Progress = progress.ToString();
            if (!starting && progress < WATCHED_PERCENT)
            {
                state = TraktScrobbleStates.cancelwatching;
            }

            scrobbleData.PluginVersion        = TraktSettings.Version;
            scrobbleData.MediaCenter          = "MediaPortal 2";
            scrobbleData.MediaCenterVersion   = Assembly.GetEntryAssembly().GetName().Version.ToString();
            scrobbleData.MediaCenterBuildDate = String.Empty;
            scrobbleData.Username             = username;
            scrobbleData.Password             = password;
            return(true);
        }
コード例 #10
0
ファイル: TraktHandler.cs プロジェクト: nagyist/MediaPortal-2
        private string GetSeriesTitle(MediaItem currMediaItem)
        {
            string value;

            return(MediaItemAspect.TryGetAttribute(currMediaItem.Aspects, SeriesAspect.ATTR_SERIESNAME, out value) ? value : null);
        }
コード例 #11
0
 protected Guid GetOrAddDirectory(IFileSystemResourceAccessor directoryAccessor, Guid parentDirectoryId,
     IMediaBrowsing mediaBrowsing, IImportResultHandler resultHandler)
 {
   ResourcePath directoryPath = directoryAccessor.CanonicalLocalResourcePath;
   MediaItem directoryItem = mediaBrowsing.LoadLocalItem(directoryPath, EMPTY_MIA_ID_ENUMERATION, DIRECTORY_MIA_ID_ENUMERATION);
   if (directoryItem != null)
   {
     MediaItemAspect da;
     if (!directoryItem.Aspects.TryGetValue(DirectoryAspect.ASPECT_ID, out da))
     { // This is the case if the path was formerly imported as a non-directory media item; we cannot reuse it
       resultHandler.DeleteMediaItem(directoryPath);
       directoryItem = null;
     }
   }
   if (directoryItem == null)
   { // Add directory item to ML
     MediaItemAspect mia = new MediaItemAspect(MediaAspect.Metadata);
     mia.SetAttribute(MediaAspect.ATTR_TITLE, directoryAccessor.ResourceName);
     mia.SetAttribute(MediaAspect.ATTR_MIME_TYPE, null);
     mia.SetAttribute(MediaAspect.ATTR_RECORDINGTIME, DateTime.MinValue);
     mia.SetAttribute(MediaAspect.ATTR_RATING, 0);
     mia.SetAttribute(MediaAspect.ATTR_COMMENT, null);
     mia.SetAttribute(MediaAspect.ATTR_LASTPLAYED, DateTime.MinValue);
     MediaItemAspect da = new MediaItemAspect(DirectoryAspect.Metadata);
     IList<MediaItemAspect> aspects = new List<MediaItemAspect>(new[]
       {
           mia,
           da,
       });
     return resultHandler.UpdateMediaItem(parentDirectoryId, directoryPath, aspects);
   }
   return directoryItem.MediaItemId;
 }
コード例 #12
0
        public void TestReconcileMediaItem()
        {
            //TODO: Update below code to work with ML changes
            return;

            MockCore.SetupLibrary(true);

            ServiceRegistration.Set <IPluginManager>(new MockPluginManager());

            MockRelationshipExtractor extractor = new MockRelationshipExtractor();

            MockMediaAccessor accessor = new MockMediaAccessor();

            accessor.AddRelationshipExtractor(extractor);
            ServiceRegistration.Set <IMediaAccessor>(accessor);
            ServiceRegistration.Get <IMediaAccessor>().Initialize();

            MockCore.Management.AddMediaItemAspectStorage(EpisodeAspect.Metadata);
            MockCore.Management.AddMediaItemAspectStorage(ExternalIdentifierAspect.Metadata);
            MockCore.Management.AddMediaItemAspectStorage(ImporterAspect.Metadata);
            MockCore.Management.AddMediaItemAspectStorage(MediaAspect.Metadata);
            MockCore.Management.AddMediaItemAspectStorage(ProviderResourceAspect.Metadata);
            MockCore.Management.AddMediaItemAspectStorage(RelationshipAspect.Metadata);
            MockCore.Management.AddMediaItemAspectStorage(SeasonAspect.Metadata);
            MockCore.Management.AddMediaItemAspectStorage(SeriesAspect.Metadata);

            Guid episodeItemId = new Guid("aaaaaaaa-1111-1111-1111-aaaaaaaaaaaa");
            Guid seasonItemId  = new Guid("bbbbbbbb-2222-2222-2222-bbbbbbbbbbbb");
            Guid seriesItemId  = new Guid("cccccccc-3333-3333-3333-cccccccccccc");

            string seriesName        = "The Series";
            string seriesDescription = "The adventures of some characters";

            int    episode           = 1;
            string episodeName       = "The Episode";
            string episodeTitle      = seriesName + ": " + episodeName;
            Guid   parentDirectoryId = new Guid("dddddddd-4444-4444-4444-dddddddddddd");

            int    season            = 2;
            string seriesSeasonName  = seriesName + " " + season;
            string seasonDescription = "Continuing adventures of some characters, several story arcs etc";

            string externalSource   = "TEST";
            string externalSeriesId = "345";

            MockCore.Library.AddMediaItemId(episodeItemId);
            MockCore.Library.AddMediaItemId(seasonItemId);
            MockCore.Library.AddMediaItemId(seriesItemId);

            string       systemId = "local";
            string       mimeType = "video/mkv";
            string       pathStr  = @"c:\item.mkv";
            ResourcePath path     = LocalFsResourceProviderBase.ToResourcePath(pathStr);
            DateTime     importDate;

            DateTime.TryParse("2014-10-11 12:34:56", out importDate);

            IDictionary <Guid, IList <MediaItemAspect> > episodeAspects = new Dictionary <Guid, IList <MediaItemAspect> >();

            MediaItemAspect.SetAttribute(episodeAspects, MediaAspect.ATTR_TITLE, episodeTitle);
            MediaItemAspect.SetCollectionAttribute(episodeAspects, EpisodeAspect.ATTR_EPISODE, new[] { episode });
            MediaItemAspect.SetAttribute(episodeAspects, EpisodeAspect.ATTR_SEASON, season);
            MultipleMediaItemAspect providerResourceAspect = MediaItemAspect.CreateAspect(episodeAspects, ProviderResourceAspect.Metadata);

            providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, mimeType);
            MediaItemAspect.AddOrUpdateExternalIdentifier(episodeAspects, externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId);
            ServiceRegistration.Get <ILogger>().Debug("Episode:");
            MockCore.ShowMediaAspects(episodeAspects, MockCore.Library.GetManagedMediaItemAspectMetadata());

            IDictionary <Guid, IList <MediaItemAspect> > seasonAspects = new Dictionary <Guid, IList <MediaItemAspect> >();

            MediaItemAspect.SetAttribute(seasonAspects, SeasonAspect.ATTR_SERIES_NAME, seriesName);
            MediaItemAspect.SetAttribute(seasonAspects, SeasonAspect.ATTR_SEASON, season);
            MediaItemAspect.SetAttribute(seasonAspects, SeasonAspect.ATTR_DESCRIPTION, seasonDescription);
            MediaItemAspect.AddOrUpdateExternalIdentifier(seasonAspects, externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId);
            ServiceRegistration.Get <ILogger>().Debug("Season:");
            MockCore.ShowMediaAspects(seasonAspects, MockCore.Library.GetManagedMediaItemAspectMetadata());

            Guid[] matchAspects = new[] { SeasonAspect.ASPECT_ID, ExternalIdentifierAspect.ASPECT_ID, MediaAspect.ASPECT_ID };
            extractor.AddRelationship(EpisodeAspect.ROLE_EPISODE, new[] { EpisodeAspect.ASPECT_ID }, SeasonAspect.ROLE_SEASON, new[] { SeasonAspect.ASPECT_ID }, matchAspects, externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId, new List <IDictionary <Guid, IList <MediaItemAspect> > >()
            {
                seasonAspects
            }, EpisodeSeasonMatcher, episode);

            IDictionary <Guid, IList <MediaItemAspect> > seriesAspects = new Dictionary <Guid, IList <MediaItemAspect> >();

            MediaItemAspect.SetAttribute(seriesAspects, SeasonAspect.ATTR_SERIES_NAME, seriesName);
            MediaItemAspect.SetAttribute(seriesAspects, SeasonAspect.ATTR_DESCRIPTION, seriesDescription);
            MediaItemAspect.AddOrUpdateExternalIdentifier(seriesAspects, externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId);
            ServiceRegistration.Get <ILogger>().Debug("Series:");
            MockCore.ShowMediaAspects(seriesAspects, MockCore.Library.GetManagedMediaItemAspectMetadata());

            matchAspects = new[] { SeriesAspect.ASPECT_ID, ExternalIdentifierAspect.ASPECT_ID, MediaAspect.ASPECT_ID };
            extractor.AddRelationship(SeasonAspect.ROLE_SEASON, new[] { SeasonAspect.ASPECT_ID }, SeriesAspect.ROLE_SERIES, new[] { SeriesAspect.ASPECT_ID }, matchAspects, externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId, new List <IDictionary <Guid, IList <MediaItemAspect> > >()
            {
                seriesAspects
            }, null, season);

            MockDBUtils.AddReader(1, "SELECT MEDIA_ITEM_ID FROM M_PROVIDERRESOURCE WHERE SYSTEM_ID = @SYSTEM_ID AND PATH = @PATH", "MEDIA_ITEM_ID");

            MockDBUtils.AddReader(2, "SELECT MEDIA_ITEM_ID FROM M_PROVIDERRESOURCE WHERE MEDIA_ITEM_ID = @MEDIA_ITEM_ID", "MEDIA_ITEM_ID");

            // Readers used by UpdateRelationships to find episode item

            MockReader reader2 = MockDBUtils.AddReader(3,
                                                       "SELECT T6.MEDIA_ITEM_ID A30, T0.MEDIA_ITEM_ID A31, T1.MEDIA_ITEM_ID A32, T2.MEDIA_ITEM_ID A33, T3.MEDIA_ITEM_ID A34, T4.MEDIA_ITEM_ID A35, T5.MEDIA_ITEM_ID A36, " +
                                                       "T0.SERIESNAME A0, T0.SEASON A1, T0.SERIESSEASONNAME A2, T0.EPISODENAME A3, T0.FIRSTAIRED A4, T0.TOTALRATING A5, T0.RATINGCOUNT A6, " +
                                                       "T1.LASTIMPORTDATE A7, T1.DIRTY A8, T1.DATEADDED A9, " +
                                                       "T2.TITLE A10, T2.RECORDINGTIME A11, T2.RATING A12, T2.COMMENT A13, T2.PLAYCOUNT A14, T2.LASTPLAYED A15, " +
                                                       "T3.SYSTEM_ID A16, T3.MIMETYPE A17, T3.SIZE A18, T3.PATH A19, T3.PARENTDIRECTORY A20, " +
                                                       "T4.SERIESNAME_0 A21, T4.SEASON_0 A22, T4.SERIESSEASONNAME_0 A23, T4.DESCRIPTION A24, T4.FIRSTAIRED_0 A25, T4.TOTALRATING_0 A26, T4.RATINGCOUNT_0 A27, " +
                                                       "T5.SERIESNAME_1 A28, T5.DESCRIPTION_0 A29 " +
                                                       "FROM MEDIA_ITEMS T6 " +
                                                       "LEFT OUTER JOIN M_EPISODEITEM T0 ON T0.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                       "LEFT OUTER JOIN M_IMPORTEDITEM T1 ON T1.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                       "LEFT OUTER JOIN M_MEDIAITEM T2 ON T2.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                       "LEFT OUTER JOIN M_PROVIDERRESOURCE T3 ON T3.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                       "LEFT OUTER JOIN M_SEASONITEM T4 ON T4.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                       "LEFT OUTER JOIN M_SERIESITEM T5 ON T5.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID  " +
                                                       "WHERE T6.MEDIA_ITEM_ID = @V0",
                                                       CreateAttributeIdList(30, 36));

            reader2.AddResult(
                episodeItemId, episodeItemId, episodeItemId, episodeItemId, episodeItemId, null, null,
                null, season, null, null, null, null, null,
                importDate, false, importDate,
                episodeTitle, null, null, null, null, null,
                systemId, mimeType, 100, @"c:\", parentDirectoryId,
                null, null, null, null, null, null, null,
                null, null
                );

            MockReader reader3 = MockDBUtils.AddReader(4,
                                                       "SELECT T0.MEDIA_ITEM_ID A0, " +
                                                       "T1.VALUE A1 " +
                                                       "FROM NM_EPISODE T0 " +
                                                       "INNER JOIN V_EPISODE T1 ON T0.VALUE_ID = T1.VALUE_ID " +
                                                       "WHERE T0.MEDIA_ITEM_ID = @V0",
                                                       "A0", "A1");

            reader3.AddResult(
                episodeItemId,
                episode);

            MockDBUtils.AddReader(5, "SELECT T0.MEDIA_ITEM_ID A0, T1.VALUE A1 FROM NM_DVDEPISODE T0 INNER JOIN V_DVDEPISODE T1 ON T0.VALUE_ID = T1.VALUE_ID WHERE T0.MEDIA_ITEM_ID = @V0", "A0", "A1");

            MockReader reader5 = MockDBUtils.AddReader(6,
                                                       "SELECT T0.MEDIA_ITEM_ID A3, T0.MEDIA_ITEM_ID A4, " +
                                                       "T0.SOURCE A0, T0.TYPE A1, T0.ID A2 " +
                                                       "FROM M_EXTERNALIDENTIFIER T0  " +
                                                       "WHERE T0.MEDIA_ITEM_ID = @V0",
                                                       CreateAttributeIdList(3, 4));

            reader5.AddResult(
                episodeItemId, episodeItemId,
                externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId);

            MockDBUtils.AddReader(7,
                                  "SELECT T0.MEDIA_ITEM_ID A4, T0.MEDIA_ITEM_ID A5, " +
                                  "T0.ROLE A0, T0.LINKEDROLE A1, T0.LINKEDID A2, T0.RELATIONSHIPINDEX A3 " +
                                  "FROM M_RELATIONSHIP T0  " +
                                  "WHERE T0.MEDIA_ITEM_ID = @V0",
                                  CreateAttributeIdList(3, 4));

            MockDBUtils.AddReader(8,
                                  "SELECT T0.MEDIA_ITEM_ID A4, T0.MEDIA_ITEM_ID A5, T0.ROLE A0, T0.LINKEDROLE A1, T0.LINKEDID A2, T0.RELATIONSHIPINDEX A3 FROM M_RELATIONSHIP T0  WHERE T0.LINKEDID IN (@V0)");

            // Readers used by UpdateRelationships to find season item

            MockDBUtils.AddReader(9,
                                  "SELECT T0.MEDIA_ITEM_ID A30, T0.MEDIA_ITEM_ID A31, T1.MEDIA_ITEM_ID A32, T2.MEDIA_ITEM_ID A33, T3.MEDIA_ITEM_ID A34, T4.MEDIA_ITEM_ID A35, T5.MEDIA_ITEM_ID A36, " +
                                  "T0.SERIESNAME_0 A0, T0.SEASON_0 A1, T0.SERIESSEASONNAME_0 A2, T0.DESCRIPTION A3, T0.FIRSTAIRED_0 A4, T0.TOTALRATING_0 A5, T0.RATINGCOUNT_0 A6, " +
                                  "T1.TITLE A7, T1.RECORDINGTIME A8, T1.RATING A9, T1.COMMENT A10, T1.PLAYCOUNT A11, T1.LASTPLAYED A12, " +
                                  "T2.SERIESNAME A13, T2.SEASON A14, T2.SERIESSEASONNAME A15, T2.EPISODENAME A16, T2.FIRSTAIRED A17, T2.TOTALRATING A18, T2.RATINGCOUNT A19, " +
                                  "T3.LASTIMPORTDATE A20, T3.DIRTY A21, T3.DATEADDED A22, " +
                                  "T4.SYSTEM_ID A23, T4.MIMETYPE A24, T4.SIZE A25, T4.PATH A26, T4.PARENTDIRECTORY A27, " +
                                  "T5.SERIESNAME_1 A28, T5.DESCRIPTION_0 A29 " +
                                  "FROM M_SEASONITEM T0 " +
                                  "INNER JOIN M_MEDIAITEM T1 ON T1.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID " +
                                  "LEFT OUTER JOIN M_EPISODEITEM T2 ON T2.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID " +
                                  "LEFT OUTER JOIN M_IMPORTEDITEM T3 ON T3.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID " +
                                  "LEFT OUTER JOIN M_PROVIDERRESOURCE T4 ON T4.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID " +
                                  "LEFT OUTER JOIN M_SERIESITEM T5 ON T5.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID  " +
                                  "WHERE T0.MEDIA_ITEM_ID IN(SELECT MEDIA_ITEM_ID FROM M_EXTERNALIDENTIFIER WHERE SOURCE = @V0 AND TYPE = @V1 AND ID = @V2)",
                                  CreateAttributeIdList(30, 36));

            MockDBUtils.AddReader(10, "SELECT MEDIA_ITEM_ID FROM M_PROVIDERRESOURCE WHERE SYSTEM_ID = @SYSTEM_ID AND PATH = @PATH", "MEDIA_ITEM_ID");

            MockReader reader10 = MockDBUtils.AddReader(11,
                                                        "SELECT T6.MEDIA_ITEM_ID A30, T0.MEDIA_ITEM_ID A31, T1.MEDIA_ITEM_ID A32, T2.MEDIA_ITEM_ID A33, T3.MEDIA_ITEM_ID A34, T4.MEDIA_ITEM_ID A35, T5.MEDIA_ITEM_ID A36, " +
                                                        "T0.SERIESNAME A0, T0.SEASON A1, T0.SERIESSEASONNAME A2, T0.EPISODENAME A3, T0.FIRSTAIRED A4, T0.TOTALRATING A5, T0.RATINGCOUNT A6, " +
                                                        "T1.LASTIMPORTDATE A7, T1.DIRTY A8, T1.DATEADDED A9, " +
                                                        "T2.TITLE A10, T2.RECORDINGTIME A11, T2.RATING A12, T2.COMMENT A13, T2.PLAYCOUNT A14, T2.LASTPLAYED A15, " +
                                                        "T3.SYSTEM_ID A16, T3.MIMETYPE A17, T3.SIZE A18, T3.PATH A19, T3.PARENTDIRECTORY A20, " +
                                                        "T4.SERIESNAME_0 A21, T4.SEASON_0 A22, T4.SERIESSEASONNAME_0 A23, T4.DESCRIPTION A24, T4.FIRSTAIRED_0 A25, T4.TOTALRATING_0 A26, T4.RATINGCOUNT_0 A27, " +
                                                        "T5.SERIESNAME_1 A28, T5.DESCRIPTION_0 A29 " +
                                                        "FROM MEDIA_ITEMS T6 " +
                                                        "LEFT OUTER JOIN M_EPISODEITEM T0 ON T0.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_IMPORTEDITEM T1 ON T1.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_MEDIAITEM T2 ON T2.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_PROVIDERRESOURCE T3 ON T3.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_SEASONITEM T4 ON T4.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_SERIESITEM T5 ON T5.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID  " +
                                                        "WHERE T6.MEDIA_ITEM_ID = @V0",
                                                        CreateAttributeIdList(30, 36));

            reader10.AddResult(
                seasonItemId, null, seasonItemId, seasonItemId, seasonItemId, seasonItemId, null,
                null, null, null, null, null, null, null,
                importDate, false, importDate,
                seriesSeasonName, null, null, null, null, null,
                null, null, 0, null, Guid.Empty,
                seriesName, season, seriesSeasonName, seasonDescription, null, null, null,
                null, null
                );

            MockReader reader11 = MockDBUtils.AddReader(12,
                                                        "SELECT T0.MEDIA_ITEM_ID A3, T0.MEDIA_ITEM_ID A4, " +
                                                        "T0.SOURCE A0, T0.TYPE A1, T0.ID A2 " +
                                                        "FROM M_EXTERNALIDENTIFIER T0  " +
                                                        "WHERE T0.MEDIA_ITEM_ID = @V0",
                                                        CreateAttributeIdList(3, 4));

            reader11.AddResult(
                seasonItemId, seasonItemId,
                externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId);

            MockDBUtils.AddReader(13,
                                  "SELECT T0.MEDIA_ITEM_ID A4, T0.MEDIA_ITEM_ID A5, " +
                                  "T0.ROLE A0, T0.LINKEDROLE A1, T0.LINKEDID A2, T0.RELATIONSHIPINDEX A3 " +
                                  "FROM M_RELATIONSHIP T0  " +
                                  "WHERE T0.MEDIA_ITEM_ID = @V0",
                                  CreateAttributeIdList(3, 4));

            MockDBUtils.AddReader(14,
                                  "SELECT T0.MEDIA_ITEM_ID A4, T0.MEDIA_ITEM_ID A5, T0.ROLE A0, T0.LINKEDROLE A1, T0.LINKEDID A2, T0.RELATIONSHIPINDEX A3 FROM M_RELATIONSHIP T0  WHERE T0.LINKEDID IN (@V0)");

            MockDBUtils.AddReader(15,
                                  "SELECT T0.MEDIA_ITEM_ID A30, T0.MEDIA_ITEM_ID A31, T1.MEDIA_ITEM_ID A32, T2.MEDIA_ITEM_ID A33, T3.MEDIA_ITEM_ID A34, T4.MEDIA_ITEM_ID A35, T5.MEDIA_ITEM_ID A36, " +
                                  "T0.SERIESNAME_1 A0, T0.DESCRIPTION_0 A1, " +
                                  "T1.TITLE A2, T1.RECORDINGTIME A3, T1.RATING A4, T1.COMMENT A5, T1.PLAYCOUNT A6, T1.LASTPLAYED A7, " +
                                  "T2.SERIESNAME A8, T2.SEASON A9, T2.SERIESSEASONNAME A10, T2.EPISODENAME A11, T2.FIRSTAIRED A12, T2.TOTALRATING A13, T2.RATINGCOUNT A14, " +
                                  "T3.LASTIMPORTDATE A15, T3.DIRTY A16, T3.DATEADDED A17, " +
                                  "T4.SYSTEM_ID A18, T4.MIMETYPE A19, T4.SIZE A20, T4.PATH A21, T4.PARENTDIRECTORY A22, " +
                                  "T5.SERIESNAME_0 A23, T5.SEASON_0 A24, T5.SERIESSEASONNAME_0 A25, T5.DESCRIPTION A26, T5.FIRSTAIRED_0 A27, T5.TOTALRATING_0 A28, T5.RATINGCOUNT_0 A29 " +
                                  "FROM M_SERIESITEM T0 " +
                                  "INNER JOIN M_MEDIAITEM T1 ON T1.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID " +
                                  "LEFT OUTER JOIN M_EPISODEITEM T2 ON T2.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID " +
                                  "LEFT OUTER JOIN M_IMPORTEDITEM T3 ON T3.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID " +
                                  "LEFT OUTER JOIN M_PROVIDERRESOURCE T4 ON T4.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID " +
                                  "LEFT OUTER JOIN M_SEASONITEM T5 ON T5.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID  " +
                                  "WHERE T0.MEDIA_ITEM_ID IN(SELECT MEDIA_ITEM_ID FROM M_EXTERNALIDENTIFIER WHERE SOURCE = @V0 AND TYPE = @V1 AND ID = @V2)",
                                  CreateAttributeIdList(30, 36));

            MockDBUtils.AddReader(16, "SELECT MEDIA_ITEM_ID FROM M_PROVIDERRESOURCE WHERE SYSTEM_ID = @SYSTEM_ID AND PATH = @PATH", "MEDIA_ITEM_ID");

            // Readers used by UpdateRelationships to find series item

            MockReader reader16 = MockDBUtils.AddReader(17,
                                                        "SELECT T6.MEDIA_ITEM_ID A30, T0.MEDIA_ITEM_ID A31, T1.MEDIA_ITEM_ID A32, T2.MEDIA_ITEM_ID A33, T3.MEDIA_ITEM_ID A34, T4.MEDIA_ITEM_ID A35, T5.MEDIA_ITEM_ID A36, " +
                                                        "T0.SERIESNAME A0, T0.SEASON A1, T0.SERIESSEASONNAME A2, T0.EPISODENAME A3, T0.FIRSTAIRED A4, T0.TOTALRATING A5, T0.RATINGCOUNT A6, " +
                                                        "T1.LASTIMPORTDATE A7, T1.DIRTY A8, T1.DATEADDED A9, " +
                                                        "T2.TITLE A10, T2.RECORDINGTIME A11, T2.RATING A12, T2.COMMENT A13, T2.PLAYCOUNT A14, T2.LASTPLAYED A15, " +
                                                        "T3.SYSTEM_ID A16, T3.MIMETYPE A17, T3.SIZE A18, T3.PATH A19, T3.PARENTDIRECTORY A20, " +
                                                        "T4.SERIESNAME_0 A21, T4.SEASON_0 A22, T4.SERIESSEASONNAME_0 A23, T4.DESCRIPTION A24, T4.FIRSTAIRED_0 A25, T4.TOTALRATING_0 A26, T4.RATINGCOUNT_0 A27, " +
                                                        "T5.SERIESNAME_1 A28, T5.DESCRIPTION_0 A29 " +
                                                        "FROM MEDIA_ITEMS T6 " +
                                                        "LEFT OUTER JOIN M_EPISODEITEM T0 ON T0.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_IMPORTEDITEM T1 ON T1.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_MEDIAITEM T2 ON T2.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_PROVIDERRESOURCE T3 ON T3.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_SEASONITEM T4 ON T4.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID " +
                                                        "LEFT OUTER JOIN M_SERIESITEM T5 ON T5.MEDIA_ITEM_ID = T6.MEDIA_ITEM_ID  " +
                                                        "WHERE T6.MEDIA_ITEM_ID = @V0",
                                                        CreateAttributeIdList(30, 36));

            reader16.AddResult(
                seriesItemId, null, seasonItemId, seasonItemId, seasonItemId, null, seriesItemId,
                null, null, null, null, null, null, null,
                importDate, false, importDate,
                seriesName, null, null, null, null, null,
                null, null, 0, null, Guid.Empty,
                null, null, null, null, null, null, null,
                seriesName, seriesDescription
                );

            MockReader reader17 = MockDBUtils.AddReader(18,
                                                        "SELECT T0.MEDIA_ITEM_ID A3, T0.MEDIA_ITEM_ID A4, " +
                                                        "T0.SOURCE A0, T0.TYPE A1, T0.ID A2 " +
                                                        "FROM M_EXTERNALIDENTIFIER T0  " +
                                                        "WHERE T0.MEDIA_ITEM_ID = @V0",
                                                        CreateAttributeIdList(3, 4));

            reader17.AddResult(
                seriesItemId, seriesItemId,
                externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId);

            MockDBUtils.AddReader(19,
                                  "SELECT T0.MEDIA_ITEM_ID A4, T0.MEDIA_ITEM_ID A5, " +
                                  "T0.ROLE A0, T0.LINKEDROLE A1, T0.LINKEDID A2, T0.RELATIONSHIPINDEX A3 " +
                                  "FROM M_RELATIONSHIP T0  " +
                                  "WHERE T0.MEDIA_ITEM_ID = @V0",
                                  CreateAttributeIdList(4, 5));

            MockDBUtils.AddReader(20,
                                  "SELECT T0.MEDIA_ITEM_ID A4, T0.MEDIA_ITEM_ID A5, T0.ROLE A0, T0.LINKEDROLE A1, T0.LINKEDID A2, T0.RELATIONSHIPINDEX A3 FROM M_RELATIONSHIP T0  WHERE T0.LINKEDID IN (@V0)");

            MockReader reader20 = MockDBUtils.AddReader(21,
                                                        "SELECT MEDIA_ITEM_ID " +
                                                        "FROM M_EXTERNALIDENTIFIER " +
                                                        "WHERE MEDIA_ITEM_ID = @MEDIA_ITEM_ID AND SOURCE = @SOURCE AND TYPE = @TYPE",
                                                        "MEDIA_ITEM_ID");

            reader20.AddResult(
                seasonItemId,
                externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId);

            MockDBUtils.AddReader(22,
                                  "SELECT MEDIA_ITEM_ID " +
                                  "FROM M_RELATIONSHIP " +
                                  "WHERE MEDIA_ITEM_ID = @MEDIA_ITEM_ID AND ROLE = @ROLE AND LINKEDROLE = @LINKEDROLE AND LINKEDID = @LINKEDID",
                                  "MEDIA_ITEM_ID");

            MockReader reader22 = MockDBUtils.AddReader(23,
                                                        "SELECT MEDIA_ITEM_ID " +
                                                        "FROM M_EXTERNALIDENTIFIER " +
                                                        "WHERE MEDIA_ITEM_ID = @MEDIA_ITEM_ID AND SOURCE = @SOURCE AND TYPE = @TYPE",
                                                        "MEDIA_ITEM_ID");

            reader22.AddResult(
                seasonItemId,
                externalSource, ExternalIdentifierAspect.TYPE_SERIES, externalSeriesId);

            MockDBUtils.AddReader(24,
                                  "SELECT MEDIA_ITEM_ID " +
                                  "FROM M_RELATIONSHIP " +
                                  "WHERE MEDIA_ITEM_ID = @MEDIA_ITEM_ID AND ROLE = @ROLE AND LINKEDROLE = @LINKEDROLE AND LINKEDID = @LINKEDID",
                                  "MEDIA_ITEM_ID");

            MockCore.Library.AddOrUpdateMediaItem(parentDirectoryId, systemId, path, episodeAspects.Values.SelectMany(x => x), true);

            MockCore.ShutdownLibrary();
        }
コード例 #13
0
        public override bool FromMetadata(IDictionary <Guid, IList <MediaItemAspect> > aspectData)
        {
            if (!aspectData.ContainsKey(AudioAspect.ASPECT_ID))
            {
                return(false);
            }

            GetMetadataChanged(aspectData);

            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_TRACKNAME, out TrackName);
            MediaItemAspect.TryGetAttribute(aspectData, MediaAspect.ATTR_SORT_TITLE, out TrackNameSort);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_LYRICS, out TrackLyrics);
            MediaItemAspect.TryGetAttribute(aspectData, MediaAspect.ATTR_RECORDINGTIME, out ReleaseDate);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_TRACK, out TrackNum);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_NUMTRACKS, out TotalTracks);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_COMPILATION, out Compilation);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_BITRATE, out BitRate);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_SAMPLERATE, out SampleRate);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_CHANNELS, out Channels);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_ALBUM, out Album);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_DISCID, out DiscNum);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_NUMDISCS, out TotalDiscs);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_DURATION, out Duration);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_ENCODING, out Encoding);
            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_CONTENT_GROUP, out ContentGroup);

            double?rating;

            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_TOTAL_RATING, out rating);
            int?voteCount;

            MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_RATING_COUNT, out voteCount);
            Rating = new SimpleRating(rating, voteCount);

            CustomIds.Clear();
            CustomAlbumIds.Clear();
            IList <MultipleMediaItemAspect> externalIdAspects;

            if (MediaItemAspect.TryGetAspects(aspectData, ExternalIdentifierAspect.Metadata, out externalIdAspects))
            {
                foreach (MultipleMediaItemAspect externalId in externalIdAspects)
                {
                    string source = externalId.GetAttributeValue <string>(ExternalIdentifierAspect.ATTR_SOURCE);
                    string id     = externalId.GetAttributeValue <string>(ExternalIdentifierAspect.ATTR_ID);
                    string type   = externalId.GetAttributeValue <string>(ExternalIdentifierAspect.ATTR_TYPE);
                    if (type == ExternalIdentifierAspect.TYPE_TRACK)
                    {
                        if (source == ExternalIdentifierAspect.SOURCE_AUDIODB)
                        {
                            AudioDbId = Convert.ToInt32(id);
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_LYRIC)
                        {
                            LyricId = Convert.ToInt32(id);
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_MVDB)
                        {
                            MvDbId = Convert.ToInt32(id);
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_MUSICBRAINZ)
                        {
                            MusicBrainzId = id;
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_ISRC)
                        {
                            IsrcId = id;
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_MUSIC_IP)
                        {
                            MusicIpId = id;
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_NAME)
                        {
                            NameId = id;
                        }
                        else
                        {
                            CustomIds.Add(source, id);
                        }
                    }
                    else if (type == ExternalIdentifierAspect.TYPE_ALBUM)
                    {
                        if (source == ExternalIdentifierAspect.SOURCE_AUDIODB)
                        {
                            AlbumAudioDbId = Convert.ToInt32(id);
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_MUSICBRAINZ)
                        {
                            AlbumMusicBrainzId = id;
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_MUSICBRAINZ_GROUP)
                        {
                            AlbumMusicBrainzGroupId = id;
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_CDDB)
                        {
                            AlbumCdDdId = id;
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_UPCEAN)
                        {
                            AlbumUpcEanId = id;
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_AMAZON)
                        {
                            AlbumAmazonId = id;
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_ITUNES)
                        {
                            AlbumItunesId = id;
                        }
                        else if (source == ExternalIdentifierAspect.SOURCE_NAME)
                        {
                            AlbumNameId = id;
                        }
                        else
                        {
                            CustomAlbumIds.Add(source, id);
                        }
                    }
                }
            }

            //Brownard 17.06.2016
            //The returned type of the collection differs on the server and client.
            //On the server it's an object collection but on the client it's a string collection due to [de]serialization.
            //Use the non generic Ienumerable to allow for both types.
            IEnumerable collection;

            Artists.Clear();
            if (MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_ARTISTS, out collection))
            {
                Artists.AddRange(collection.Cast <string>().Select(s => new PersonInfo {
                    Name = s, Occupation = PersonAspect.OCCUPATION_ARTIST, MediaName = TrackName, ParentMediaName = Album
                }));
            }
            foreach (PersonInfo artist in Artists)
            {
                artist.AssignNameId();
            }

            AlbumArtists.Clear();
            if (MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_ALBUMARTISTS, out collection))
            {
                AlbumArtists.AddRange(collection.Cast <string>().Select(s => new PersonInfo {
                    Name = s, Occupation = PersonAspect.OCCUPATION_ARTIST, MediaName = TrackName, ParentMediaName = Album
                }));
            }
            foreach (PersonInfo artist in AlbumArtists)
            {
                artist.AssignNameId();
            }

            Composers.Clear();
            if (MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_COMPOSERS, out collection))
            {
                Composers.AddRange(collection.Cast <string>().Select(s => new PersonInfo {
                    Name = s, Occupation = PersonAspect.OCCUPATION_COMPOSER, MediaName = TrackName, ParentMediaName = Album
                }));
            }
            foreach (PersonInfo composer in Composers)
            {
                composer.AssignNameId();
            }

            Conductors.Clear();
            if (MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_CONDUCTERS, out collection))
            {
                Conductors.AddRange(collection.Cast <string>().Select(s => new PersonInfo {
                    Name = s, Occupation = PersonAspect.OCCUPATION_CONDUCTOR, MediaName = TrackName, ParentMediaName = Album
                }));
            }
            foreach (PersonInfo conductor in Conductors)
            {
                conductor.AssignNameId();
            }

            Genres.Clear();
            IList <MultipleMediaItemAspect> genreAspects;

            if (MediaItemAspect.TryGetAspects(aspectData, GenreAspect.Metadata, out genreAspects))
            {
                foreach (MultipleMediaItemAspect genre in genreAspects)
                {
                    Genres.Add(new GenreInfo
                    {
                        Id   = genre.GetAttributeValue <int?>(GenreAspect.ATTR_ID),
                        Name = genre.GetAttributeValue <string>(GenreAspect.ATTR_GENRE)
                    });
                }
            }

            byte[] data;
            if (MediaItemAspect.TryGetAttribute(aspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, out data))
            {
                HasThumbnail = true;
            }

            return(true);
        }
コード例 #14
0
        /// <summary>
        /// Copies the contained track information into MediaItemAspect.
        /// </summary>
        /// <param name="aspectData">Dictionary with extracted aspects.</param>
        public override bool SetMetadata(IDictionary <Guid, IList <MediaItemAspect> > aspectData, bool force = false)
        {
            if (!force && !IsBaseInfoPresent)
            {
                return(false);
            }

            AssignNameId();
            SetMetadataChanged(aspectData);

            MediaItemAspect.SetAttribute(aspectData, MediaAspect.ATTR_TITLE, ToString());
            if (!string.IsNullOrEmpty(TrackNameSort))
            {
                MediaItemAspect.SetAttribute(aspectData, MediaAspect.ATTR_SORT_TITLE, TrackNameSort);
            }
            MediaItemAspect.SetAttribute(aspectData, MediaAspect.ATTR_ISVIRTUAL, IsVirtualResource(aspectData));
            MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_TRACKNAME, TrackName);
            MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_COMPILATION, Compilation);
            if (!string.IsNullOrEmpty(TrackLyrics))
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_LYRICS, TrackLyrics);
            }
            if (ReleaseDate.HasValue)
            {
                MediaItemAspect.SetAttribute(aspectData, MediaAspect.ATTR_RECORDINGTIME, ReleaseDate.Value);
            }
            if (TrackNum > 0)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_TRACK, TrackNum);
            }
            if (TotalTracks > 0)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_NUMTRACKS, TotalTracks);
            }
            if (Duration > 0)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_DURATION, Duration);
            }

            bool?isCd;

            if (!MediaItemAspect.TryGetAttribute(aspectData, AudioAspect.ATTR_ISCD, out isCd) || !isCd.HasValue)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_ISCD, false);
            }

            if (!string.IsNullOrEmpty(MusicBrainzId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_MUSICBRAINZ, ExternalIdentifierAspect.TYPE_TRACK, MusicBrainzId);
            }
            if (!string.IsNullOrEmpty(IsrcId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_ISRC, ExternalIdentifierAspect.TYPE_TRACK, IsrcId);
            }
            if (!string.IsNullOrEmpty(MusicIpId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_MUSIC_IP, ExternalIdentifierAspect.TYPE_TRACK, MusicIpId);
            }
            if (AudioDbId > 0)
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_AUDIODB, ExternalIdentifierAspect.TYPE_TRACK, AudioDbId.ToString());
            }
            if (LyricId > 0)
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_LYRIC, ExternalIdentifierAspect.TYPE_TRACK, LyricId.ToString());
            }
            if (MvDbId > 0)
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_MVDB, ExternalIdentifierAspect.TYPE_TRACK, MvDbId.ToString());
            }
            if (!string.IsNullOrEmpty(NameId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_NAME, ExternalIdentifierAspect.TYPE_TRACK, NameId);
            }
            foreach (var customId in CustomIds)
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, customId.Key, ExternalIdentifierAspect.TYPE_TRACK, customId.Value);
            }

            if (!string.IsNullOrEmpty(Album))
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_ALBUM, Album);
            }
            if (DiscNum > 0)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_DISCID, DiscNum);
            }
            if (TotalDiscs > 0)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_NUMDISCS, TotalDiscs);
            }
            if (BitRate > 0)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_BITRATE, BitRate);
            }
            if (Channels > 0)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_CHANNELS, Channels);
            }
            if (SampleRate > 0)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_SAMPLERATE, SampleRate);
            }
            if (!string.IsNullOrEmpty(Encoding))
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_ENCODING, Encoding);
            }
            if (!string.IsNullOrEmpty(ContentGroup))
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_CONTENT_GROUP, ContentGroup);
            }

            if (!Rating.IsEmpty)
            {
                MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_TOTAL_RATING, Rating.RatingValue.Value);
                if (Rating.VoteCount.HasValue)
                {
                    MediaItemAspect.SetAttribute(aspectData, AudioAspect.ATTR_RATING_COUNT, Rating.VoteCount.Value);
                }
            }

            if (!string.IsNullOrEmpty(AlbumUpcEanId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_UPCEAN, ExternalIdentifierAspect.TYPE_ALBUM, AlbumUpcEanId);
            }
            if (!string.IsNullOrEmpty(AlbumCdDdId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_CDDB, ExternalIdentifierAspect.TYPE_ALBUM, AlbumCdDdId);
            }
            if (!string.IsNullOrEmpty(AlbumMusicBrainzId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_MUSICBRAINZ, ExternalIdentifierAspect.TYPE_ALBUM, AlbumMusicBrainzId);
            }
            if (!string.IsNullOrEmpty(AlbumMusicBrainzGroupId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_MUSICBRAINZ_GROUP, ExternalIdentifierAspect.TYPE_ALBUM, AlbumMusicBrainzGroupId);
            }
            if (AlbumAudioDbId > 0)
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_AUDIODB, ExternalIdentifierAspect.TYPE_ALBUM, AlbumAudioDbId.ToString());
            }
            if (!string.IsNullOrEmpty(AlbumAmazonId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_AMAZON, ExternalIdentifierAspect.TYPE_ALBUM, AlbumAmazonId);
            }
            if (!string.IsNullOrEmpty(AlbumItunesId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_ITUNES, ExternalIdentifierAspect.TYPE_ALBUM, AlbumItunesId);
            }
            if (!string.IsNullOrEmpty(AlbumNameId))
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, ExternalIdentifierAspect.SOURCE_NAME, ExternalIdentifierAspect.TYPE_ALBUM, AlbumNameId);
            }
            foreach (var customId in CustomAlbumIds)
            {
                MediaItemAspect.AddOrUpdateExternalIdentifier(aspectData, customId.Key, ExternalIdentifierAspect.TYPE_ALBUM, customId.Value);
            }

            if (Artists.Count > 0)
            {
                MediaItemAspect.SetCollectionAttribute(aspectData, AudioAspect.ATTR_ARTISTS, Artists.Where(p => !string.IsNullOrEmpty(p.Name)).Select(p => p.Name).Distinct().ToList());
            }
            if (AlbumArtists.Count > 0)
            {
                MediaItemAspect.SetCollectionAttribute(aspectData, AudioAspect.ATTR_ALBUMARTISTS, AlbumArtists.Where(p => !string.IsNullOrEmpty(p.Name)).Select(p => p.Name).Distinct().ToList());
            }
            if (Composers.Count > 0)
            {
                MediaItemAspect.SetCollectionAttribute(aspectData, AudioAspect.ATTR_COMPOSERS, Composers.Where(p => !string.IsNullOrEmpty(p.Name)).Select(p => p.Name).Distinct().ToList());
            }
            if (Conductors.Count > 0)
            {
                MediaItemAspect.SetCollectionAttribute(aspectData, AudioAspect.ATTR_CONDUCTERS, Conductors.Where(p => !string.IsNullOrEmpty(p.Name)).Select(p => p.Name).Distinct().ToList());
            }

            aspectData.Remove(GenreAspect.ASPECT_ID);
            foreach (GenreInfo genre in Genres.Distinct())
            {
                MultipleMediaItemAspect genreAspect = MediaItemAspect.CreateAspect(aspectData, GenreAspect.Metadata);
                genreAspect.SetAttribute(GenreAspect.ATTR_ID, genre.Id);
                genreAspect.SetAttribute(GenreAspect.ATTR_GENRE, genre.Name);
            }

            SetThumbnailMetadata(aspectData);

            return(true);
        }
コード例 #15
0
ファイル: TestLibrary.cs プロジェクト: zeroxist/MediaPortal-2
        public void TestMediaItemsLoader_SingleAndMultipleMIAs_BooleanLikeFilter()
        {
            MockDBUtils.Reset();
            SingleTestMIA   mia1 = TestBackendUtils.CreateSingleMIA("SINGLE1", Cardinality.Inline, true, true);
            MultipleTestMIA mia2 = TestBackendUtils.CreateMultipleMIA("MULTIPLE2", Cardinality.Inline, true, false);
            MultipleTestMIA mia3 = TestBackendUtils.CreateMultipleMIA("MULTIPLE3", Cardinality.Inline, false, true);

            Guid itemId0 = new Guid("aaaaaaaa-1111-1111-1111-aaaaaaaaaaaa");
            Guid itemId1 = new Guid("bbbbbbbb-2222-2222-2222-bbbbbbbbbbbb");

            IFilter filter = new BooleanCombinationFilter(BooleanOperator.And, new List <IFilter> {
                new LikeFilter(mia1.ATTR_STRING, "%", null), new LikeFilter(mia2.ATTR_STRING, "%", null)
            });

            MockReader reader = MockDBUtils.AddReader(1, "SELECT T0.MEDIA_ITEM_ID A2, T0.MEDIA_ITEM_ID A3, T1.MEDIA_ITEM_ID A4, T0.ATTR_STRING A0, T0.ATTR_INTEGER A1 " +
                                                      "FROM M_SINGLE1 T0 INNER JOIN M_MULTIPLE2 T1 ON T1.MEDIA_ITEM_ID = T0.MEDIA_ITEM_ID " +
                                                      " WHERE T0.MEDIA_ITEM_ID IN(SELECT MEDIA_ITEM_ID FROM M_MULTIPLE2 WHERE ATTR_STRING LIKE @V0) AND T0.ATTR_STRING LIKE @V1", "A2", "A3", "A4", "A0", "A1");

            reader.AddResult(itemId0, itemId0, itemId0, "zero", 0, "0_0");
            reader.AddResult(itemId1, itemId1, itemId1, "one", 1, "1_1");

            MockReader multipleReader2 = MockDBUtils.AddReader(2, "SELECT T0.MEDIA_ITEM_ID A2, T0.MEDIA_ITEM_ID A3, T0.ATTR_ID A0, T0.ATTR_STRING A1 FROM M_MULTIPLE2 T0  WHERE T0.MEDIA_ITEM_ID IN (@V0, @V1)", "A2", "A3", "A0", "A1");

            multipleReader2.AddResult(itemId0, itemId0, "0_0", "zerozero");
            multipleReader2.AddResult(itemId0, itemId0, "0_1", "zeroone");
            multipleReader2.AddResult(itemId1, itemId1, "1_0", "onezero");

            MockReader multipleReader3 = MockDBUtils.AddReader(3, "SELECT T0.MEDIA_ITEM_ID A2, T0.MEDIA_ITEM_ID A3, T0.ATTR_ID A0, T0.ATTR_INTEGER A1 FROM M_MULTIPLE3 T0  WHERE T0.MEDIA_ITEM_ID IN (@V0, @V1)", "A2", "A3", "A0", "A1");

            multipleReader3.AddResult(itemId0, itemId0, "1_0", 10);
            multipleReader3.AddResult(itemId0, itemId0, "1_1", 11);
            multipleReader3.AddResult(itemId0, itemId0, "1_2", 12);
            multipleReader3.AddResult(itemId0, itemId0, "1_3", 13);
            multipleReader3.AddResult(itemId0, itemId0, "1_4", 14);
            multipleReader3.AddResult(itemId1, itemId1, "1_0", 20);

            Guid[]                 requiredAspects = { mia1.ASPECT_ID, mia2.ASPECT_ID };
            Guid[]                 optionalAspects = { mia3.ASPECT_ID };
            MediaItemQuery         query           = new MediaItemQuery(requiredAspects, optionalAspects, filter);
            CompiledMediaItemQuery compiledQuery   = CompiledMediaItemQuery.Compile(MockCore.Management, query);
            IList <MediaItem>      results         = compiledQuery.QueryList();

            /*
             * foreach (MediaItem result in results)
             *  //Console.WriteLine("Query result " + result.MediaItemId + ": " + string.Join(",", result.Aspects.Values) + ": " + result);
             */

            SingleMediaItemAspect           value;
            IList <MultipleMediaItemAspect> values;

            Assert.AreEqual(2, results.Count, "Results count");

            Assert.AreEqual(itemId0, results[0].MediaItemId, "MediaItem ID #0");
            Assert.IsTrue(MediaItemAspect.TryGetAspect(results[0].Aspects, mia1.Metadata, out value), "MIA1 #0");
            Assert.AreEqual("zero", value.GetAttributeValue(mia1.ATTR_STRING), "MIA1 string attibute #0");
            Assert.AreEqual(0, value.GetAttributeValue(mia1.ATTR_INTEGER), "MIA1 integer attibute #0");
            Assert.IsTrue(MediaItemAspect.TryGetAspects(results[0].Aspects, mia2.Metadata, out values), "MIA2 #0");
            Assert.AreEqual(2, values.Count, "MIA2 count #0");
            Assert.AreEqual("zerozero", values[0].GetAttributeValue(mia2.ATTR_STRING), "MIA2 string attibute 0 #0");
            Assert.AreEqual("zeroone", values[1].GetAttributeValue(mia2.ATTR_STRING), "MIA2 string attibute 1 #0");
            Assert.IsTrue(MediaItemAspect.TryGetAspects(results[0].Aspects, mia3.Metadata, out values), "MIA3 #0");
            Assert.AreEqual(5, values.Count, "MIA3 count #0");
            Assert.AreEqual(10, values[0].GetAttributeValue(mia3.ATTR_INTEGER), "MIA3 integer attibute 0 #0");
            Assert.AreEqual(11, values[1].GetAttributeValue(mia3.ATTR_INTEGER), "MIA3 integer attibute 1 #0");
            Assert.AreEqual(12, values[2].GetAttributeValue(mia3.ATTR_INTEGER), "MIA3 integer attibute 2 #0");
            Assert.AreEqual(13, values[3].GetAttributeValue(mia3.ATTR_INTEGER), "MIA3 integer attibute 3 #0");
            Assert.AreEqual(14, values[4].GetAttributeValue(mia3.ATTR_INTEGER), "MIA3 integer attibute 4 #0");

            Assert.AreEqual(itemId1, results[1].MediaItemId, "MediaItem ID #1");
            Assert.IsTrue(MediaItemAspect.TryGetAspect(results[1].Aspects, mia1.Metadata, out value), "MIA1 #0");
            Assert.AreEqual("one", value.GetAttributeValue(mia1.ATTR_STRING), "MIA1 string attibute #1");
            Assert.AreEqual(1, value.GetAttributeValue(mia1.ATTR_INTEGER), "MIA1 integer attibute #1");
            Assert.IsTrue(MediaItemAspect.TryGetAspects(results[1].Aspects, mia2.Metadata, out values), "MIA2 #1");
            Assert.AreEqual(1, values.Count, "MIA2 count #1");
            Assert.AreEqual("onezero", values[0].GetAttributeValue(mia2.ATTR_STRING), "MIA2 string attibute 0 #1");
            Assert.IsTrue(MediaItemAspect.TryGetAspects(results[1].Aspects, mia3.Metadata, out values), "MIA3 #0");
            Assert.AreEqual(1, values.Count, "MIA3 count #1");
            Assert.AreEqual(20, values[0].GetAttributeValue(mia3.ATTR_INTEGER), "MIA3 integer attibute 0 #1");
        }
コード例 #16
0
        /// <summary>
        /// Imports or refreshes the directory with the specified <paramref name="directoryAccessor"/>. Sub directories will not
        /// be processed in this method.
        /// </summary>
        /// <param name="importJob">The import job being processed.</param>
        /// <param name="parentDirectoryId">Media item id of the parent directory, if present, else <see cref="Guid.Empty"/>.</param>
        /// <param name="directoryAccessor">Resource accessor for the directory to import.</param>
        /// <param name="metadataExtractors">Metadata extractors to apply on the resources.</param>
        /// <param name="mediaBrowsing">Callback interface to the media library for the refresh import type.</param>
        /// <param name="resultHandler">Callback to notify the import result.</param>
        /// <param name="mediaAccessor">Convenience reference to the media accessor.</param>
        /// <returns>Id of the directory's media item or <c>null</c>, if the given <paramref name="directoryAccessor"/>
        /// was imported as a media item or if an error occured. If <c>null</c> is returned, the directory import should be
        /// considered to be finished.</returns>
        protected Guid?ImportDirectory(ImportJob importJob, Guid parentDirectoryId, IFileSystemResourceAccessor directoryAccessor,
                                       ICollection <IMetadataExtractor> metadataExtractors, IMediaBrowsing mediaBrowsing,
                                       IImportResultHandler resultHandler, IMediaAccessor mediaAccessor)
        {
            ResourcePath currentDirectoryPath = directoryAccessor.CanonicalLocalResourcePath;

            try
            {
                ImporterWorkerMessaging.SendImportMessage(ImporterWorkerMessaging.MessageType.ImportStatus, currentDirectoryPath);
                if (ImportResource(importJob, directoryAccessor, parentDirectoryId, metadataExtractors, resultHandler, mediaAccessor))
                {
                    // The directory could be imported as a media item.
                    // If the directory itself was identified as a normal media item, don't import its children.
                    // Necessary for DVD directories, for example.
                    return(null);
                }
                Guid directoryId = GetOrAddDirectory(importJob, directoryAccessor, parentDirectoryId, mediaBrowsing, resultHandler);
                IDictionary <string, MediaItem> path2Item = new Dictionary <string, MediaItem>();
                if (importJob.JobType == ImportJobType.Refresh)
                {
                    foreach (MediaItem mediaItem in mediaBrowsing.BrowseAsync(directoryId,
                                                                              IMPORTER_PROVIDER_MIA_ID_ENUMERATION, EMPTY_MIA_ID_ENUMERATION, null, false).Result)
                    {
                        IList <MultipleMediaItemAspect> providerResourceAspects;
                        if (MediaItemAspect.TryGetAspects(mediaItem.Aspects, ProviderResourceAspect.Metadata, out providerResourceAspects))
                        {
                            path2Item[providerResourceAspects[0].GetAttributeValue <string>(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH)] = mediaItem;
                        }
                    }
                }
                CheckImportStillRunning(importJob.State);
                ICollection <IFileSystemResourceAccessor> files = FileSystemResourceNavigator.GetFiles(directoryAccessor, false);
                if (files != null)
                {
                    foreach (IFileSystemResourceAccessor fileAccessor in files)
                    {
                        using (fileAccessor)
                        { // Add & update files
                            ResourcePath currentFilePath    = fileAccessor.CanonicalLocalResourcePath;
                            string       serializedFilePath = currentFilePath.Serialize();
                            try
                            {
                                SingleMediaItemAspect importerAspect;
                                MediaItem             mediaItem;
                                if (importJob.JobType == ImportJobType.Refresh &&
                                    path2Item.TryGetValue(serializedFilePath, out mediaItem) &&
                                    MediaItemAspect.TryGetAspect(mediaItem.Aspects, ImporterAspect.Metadata, out importerAspect) &&
                                    importerAspect.GetAttributeValue <DateTime>(ImporterAspect.ATTR_LAST_IMPORT_DATE) > fileAccessor.LastChanged)
                                { // We can skip this file; it was imported after the last change time of the item
                                    path2Item.Remove(serializedFilePath);
                                    continue;
                                }
                                if (ImportResource(importJob, fileAccessor, directoryId, metadataExtractors, resultHandler, mediaAccessor))
                                {
                                    path2Item.Remove(serializedFilePath);
                                }
                            }
                            catch (Exception e)
                            {
                                CheckSuspended(e); // Throw ImportAbortException if suspended - will skip warning and tagging job as erroneous
                                ServiceRegistration.Get <ILogger>().Warn("ImporterWorker: Problem while importing resource '{0}'", e, serializedFilePath);
                                importJob.State = ImportJobState.Erroneous;
                            }
                            CheckImportStillRunning(importJob.State);
                        }
                    }
                }
                if (importJob.JobType == ImportJobType.Refresh)
                { // Remove remaining (= non-present) files
                    foreach (string pathStr in path2Item.Keys)
                    {
                        ResourcePath path = ResourcePath.Deserialize(pathStr);
                        try
                        {
                            IResourceAccessor ra;
                            if (!path.TryCreateLocalResourceAccessor(out ra))
                            {
                                throw new IllegalCallException("Unable to access resource path '{0}'", importJob.BasePath);
                            }
                            using (ra)
                            {
                                IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;
                                if (fsra == null || !fsra.IsFile)
                                {
                                    // Don't touch directories because they will be imported in a different call of ImportDirectory
                                    continue;
                                }
                            }
                        }
                        catch (IllegalCallException)
                        {
                            // This happens if the resource doesn't exist any more - we also catch missing directories here
                        }
                        // Delete all remaining items
                        resultHandler.DeleteMediaItemAsync(path);
                        CheckImportStillRunning(importJob.State);
                    }
                }
                return(directoryId);
            }
            catch (ImportSuspendedException)
            {
                throw;
            }
            catch (ImportAbortException)
            {
                throw;
            }
            catch (UnauthorizedAccessException e)
            {
                // If the access to the file or folder was denied, simply continue with the others
                ServiceRegistration.Get <ILogger>().Warn("ImporterWorker: Problem accessing resource '{0}', continueing with one", e, currentDirectoryPath);
            }
            catch (Exception e)
            {
                CheckSuspended(e); // Throw ImportAbortException if suspended - will skip warning and tagging job as erroneous
                ServiceRegistration.Get <ILogger>().Warn("ImporterWorker: Problem while importing directory '{0}'", e, currentDirectoryPath);
                importJob.State = ImportJobState.Erroneous;
            }
            return(null);
        }
コード例 #17
0
        protected bool GetPattern(FanArtConstants.FanArtMediaType mediaType, FanArtConstants.FanArtType fanArtType, Guid mediaItemId, string name, out string[] patterns)
        {
            patterns = null;
            string basePath = null;

            if (mediaItemId != Guid.Empty)
            {
                IMediaLibrary mediaLibrary = ServiceRegistration.Get <IMediaLibrary>(false);
                if (mediaLibrary == null)
                {
                    return(false);
                }

                IFilter           filter = new MediaItemIdFilter(mediaItemId);
                IList <MediaItem> items  = mediaLibrary.Search(new MediaItemQuery(NECESSARY_MIAS, filter), false);
                if (items == null || items.Count == 0)
                {
                    return(false);
                }

                MediaItem mediaItem = items.First();
                int       movieDbId;
                if (MediaItemAspect.TryGetAttribute(mediaItem.Aspects, MovieAspect.ATTR_TMDB_ID, out movieDbId))
                {
                    switch (mediaType)
                    {
                    case FanArtConstants.FanArtMediaType.Undefined:
                    case FanArtConstants.FanArtMediaType.Movie:
                        basePath = Path.Combine(MovieTheMovieDbMatcher.CACHE_PATH, movieDbId.ToString());
                        break;
                    }
                }
            }
            else
            {
                switch (mediaType)
                {
                case FanArtConstants.FanArtMediaType.Undefined:
                case FanArtConstants.FanArtMediaType.Movie:
                    int movieDbId;
                    basePath = !MovieTheMovieDbMatcher.Instance.TryGetMovieDbId(name, out movieDbId) ? null : Path.Combine(MovieTheMovieDbMatcher.CACHE_PATH, movieDbId.ToString());
                    break;

                case FanArtConstants.FanArtMediaType.MovieCollection:
                    int collectionId;
                    basePath = !MovieTheMovieDbMatcher.Instance.TryGetCollectionId(name, out collectionId) ? null : Path.Combine(MovieTheMovieDbMatcher.CACHE_PATH, "COLL_" + collectionId);
                    break;
                }
            }

            if (string.IsNullOrWhiteSpace(basePath))
            {
                return(false);
            }

            switch (fanArtType)
            {
            case FanArtConstants.FanArtType.Thumbnail:
            case FanArtConstants.FanArtType.Poster:
                patterns = new[] { Path.Combine(basePath, "Posters\\*.jpg") };
                return(true);

            case FanArtConstants.FanArtType.FanArt:
                patterns = new[] { Path.Combine(basePath, "Backdrops\\*.jpg") };
                return(true);
            }
            return(false);
        }
コード例 #18
0
    public void AddOrUpdateMIA(ITransaction transaction, Guid mediaItemId, MediaItemAspect mia, bool add)
    {
      MediaItemAspectMetadata miaType;
      if (!_managedMIATypes.TryGetValue(mia.Metadata.AspectId, out miaType) || miaType == null)
        throw new ArgumentException(string.Format("MIA_Management: Requested media item aspect type with id '{0}' doesn't exist",
          mia.Metadata.AspectId));

      IList<string> terms1 = new List<string>();
      IList<string> terms2 = new List<string>();
      IList<BindVar> bindVars = new List<BindVar>();
      int ct = 0;
      string miaTableName = GetMIATableName(miaType);

      // Attributes: First run
      foreach (MediaItemAspectMetadata.AttributeSpecification spec in miaType.AttributeSpecifications.Values)
      {
        if (mia.IsIgnore(spec))
          continue;
        string attrColName;
        object attributeValue;
        string bindVarName = "V" + ct++;
        switch (spec.Cardinality)
        {
          case Cardinality.Inline:
            attrColName = GetMIAAttributeColumnName(spec);
            if (add)
            {
              terms1.Add(attrColName);
              terms2.Add("@" + bindVarName);
            }
            else
              terms1.Add(attrColName + " = @" + bindVarName);
            attributeValue = mia.GetAttributeValue(spec);
            attributeValue = TruncateBigValue(attributeValue, spec);
            bindVars.Add(new BindVar(bindVarName, AttributeIsEmpty(attributeValue) ? null : attributeValue, spec.AttributeType));
            break;
          case Cardinality.OneToMany:
            // After main query
            break;
          case Cardinality.ManyToOne:
            attrColName = GetMIAAttributeColumnName(spec);
            attributeValue = mia.GetAttributeValue(spec);
            Guid? insertValue;
            if (AttributeIsEmpty(attributeValue))
              insertValue = null;
            else
            {
              Guid valuePk;
              GetOrCreateManyToOneMIAAttributeValue(transaction, spec, mia.GetAttributeValue(spec), add, out valuePk);
              insertValue = valuePk;
            }
            if (add)
            {
              terms1.Add(attrColName);
              terms2.Add("@" + bindVarName);
            }
            else
              terms1.Add(attrColName + " = @" + bindVarName);
            bindVars.Add(new BindVar(bindVarName, insertValue.HasValue ? (Guid?) insertValue.Value : null, typeof(Guid)));
            break;
          case Cardinality.ManyToMany:
            // After main query
            break;
          default:
            throw new NotImplementedException(string.Format("Cardinality '{0}' for attribute '{1}.{2}' is not implemented",
                spec.Cardinality, miaType.AspectId, spec.AttributeName));
        }
      }
      // terms = all inline attributes
      // sqlValues = all inline attribute values
      if (add || terms1.Count > 0)
      {
        // Main query
        StringBuilder mainQueryBuilder = new StringBuilder();
        if (add)
        {
          mainQueryBuilder.Append("INSERT INTO ");
          mainQueryBuilder.Append(miaTableName);
          mainQueryBuilder.Append(" (");
        }
        else
        {
          mainQueryBuilder.Append("UPDATE ");
          mainQueryBuilder.Append(miaTableName);
          mainQueryBuilder.Append(" SET ");
        }

        mainQueryBuilder.Append(StringUtils.Join(", ", terms1));
        bindVars.Add(new BindVar("MEDIA_ITEM_ID", mediaItemId, typeof(Guid)));
        // values = all inline attribute values plus media item ID
        if (add)
        {
          if (terms1.Count > 0)
            mainQueryBuilder.Append(", ");
          mainQueryBuilder.Append(MIA_MEDIA_ITEM_ID_COL_NAME); // Append the ID column as a normal attribute
          mainQueryBuilder.Append(") VALUES (");
          terms2.Add("@MEDIA_ITEM_ID");
          mainQueryBuilder.Append(StringUtils.Join(", ", terms2));
          mainQueryBuilder.Append(")");
        }
        else
        {
          mainQueryBuilder.Append(" WHERE ");
          mainQueryBuilder.Append(MIA_MEDIA_ITEM_ID_COL_NAME); // Use the ID column in WHERE condition
          mainQueryBuilder.Append(" = @MEDIA_ITEM_ID");
        }
        ISQLDatabase database = transaction.Database;
        using (IDbCommand command = transaction.CreateCommand())
        {
          command.CommandText = mainQueryBuilder.ToString();
          foreach (BindVar bindVar in bindVars)
            database.AddParameter(command, bindVar.Name, bindVar.Value, bindVar.VariableType);
          command.ExecuteNonQuery();
        }
      }

      // Attributes: Second run
      foreach (MediaItemAspectMetadata.AttributeSpecification spec in miaType.AttributeSpecifications.Values)
      {
        if (mia.IsIgnore(spec))
          continue;
        switch (spec.Cardinality)
        {
          case Cardinality.Inline:
            break;
          case Cardinality.OneToMany:
            InsertOrUpdateOneToManyMIAAttributeValues(transaction, spec, mediaItemId, mia.GetCollectionAttribute(spec), add);
            break;
          case Cardinality.ManyToOne:
            break;
          case Cardinality.ManyToMany:
            InsertOrUpdateManyToManyMIAAttributeValues(transaction, spec, mediaItemId, mia.GetCollectionAttribute(spec), add);
            break;
          default:
            throw new NotImplementedException(string.Format("Cardinality '{0}' for attribute '{1}.{2}' is not implemented",
                spec.Cardinality, miaType.AspectId, spec.AttributeName));
        }
      }

      CleanupAllManyToOneOrphanedAttributeValues(transaction, miaType);
    }
コード例 #19
0
        public override bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            // If the base AudioMDE already extracted metadata, don't try here again to avoid conflicts.
            if (extractedAspectData.ContainsKey(AudioAspect.ASPECT_ID))
            {
                return(false);
            }

            ILocalFsResourceAccessor fsra = mediaItemAccessor as ILocalFsResourceAccessor;

            if (fsra == null)
            {
                return(false);
            }
            if (!fsra.IsFile)
            {
                return(false);
            }
            string filePath = fsra.LocalFileSystemPath;
            string fileName = fsra.ResourceName;

            if (!HasAudioExtension(fileName))
            {
                return(false);
            }

            try
            {
                var tags = BassTags.BASS_TAG_GetFromFile(filePath);
                if (tags == null)
                {
                    return(false);
                }

                fileName = ProviderPathHelper.GetFileNameWithoutExtension(fileName) ?? string.Empty;
                string title;
                string artist;
                uint?  trackNo;
                GuessMetadataFromFileName(fileName, out title, out artist, out trackNo);
                if (!string.IsNullOrWhiteSpace(tags.title))
                {
                    title = tags.title;
                }
                IEnumerable <string> artists;
                if (!string.IsNullOrWhiteSpace(tags.artist))
                {
                    artists = SplitTagEnum(tags.artist);
                    artists = PatchID3v23Enumeration(artists);
                }
                else
                {
                    artists = artist == null ? null : new string[] { artist }
                };
                if (!string.IsNullOrWhiteSpace(tags.track) && tags.track != "0")
                {
                    int iTrackNo;
                    if (int.TryParse(tags.track, out iTrackNo))
                    {
                        trackNo = (uint?)iTrackNo;
                    }
                    else
                    {
                        trackNo = null;
                    }
                }

                MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, title);
                MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_SIZE, fsra.Size);
                MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_MIME_TYPE, "audio/" + Path.GetExtension(filePath).Substring(1));
                MediaItemAspect.SetCollectionAttribute(extractedAspectData, AudioAspect.ATTR_ARTISTS, ApplyAdditionalSeparator(artists));
                MediaItemAspect.SetAttribute(extractedAspectData, AudioAspect.ATTR_ALBUM, StringUtils.TrimToNull(tags.album));
                IEnumerable <string> albumArtists = SplitTagEnum(tags.albumartist);
                albumArtists = PatchID3v23Enumeration(albumArtists);

                MediaItemAspect.SetCollectionAttribute(extractedAspectData, AudioAspect.ATTR_ALBUMARTISTS, ApplyAdditionalSeparator(albumArtists));
                MediaItemAspect.SetAttribute(extractedAspectData, AudioAspect.ATTR_BITRATE, tags.bitrate);
                MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_COMMENT, StringUtils.TrimToNull(tags.comment));
                IEnumerable <string> composers = SplitTagEnum(tags.composer);
                composers = PatchID3v23Enumeration(composers);
                MediaItemAspect.SetCollectionAttribute(extractedAspectData, AudioAspect.ATTR_COMPOSERS, ApplyAdditionalSeparator(composers));

                MediaItemAspect.SetAttribute(extractedAspectData, AudioAspect.ATTR_DURATION, (long)tags.duration);

                IEnumerable <string> genres = SplitTagEnum(tags.genre);
                genres = PatchID3v23Enumeration(genres);
                MediaItemAspect.SetCollectionAttribute(extractedAspectData, AudioAspect.ATTR_GENRES, ApplyAdditionalSeparator(genres));

                if (trackNo.HasValue)
                {
                    MediaItemAspect.SetAttribute(extractedAspectData, AudioAspect.ATTR_TRACK, (int)trackNo.Value);
                }

                int year;
                if (int.TryParse(tags.year, out year))
                {
                    if (year >= 30 && year <= 99)
                    {
                        year += 1900;
                    }
                    if (year >= 1930 && year <= 2030)
                    {
                        MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, new DateTime(year, 1, 1));
                    }
                }

                // The following code gets cover art images from file (embedded) or from windows explorer cache (supports folder.jpg).
                if (tags.PictureCount > 0)
                {
                    try
                    {
                        using (Image cover = tags.PictureGetImage(0))
                            using (Image resized = ImageUtilities.ResizeImage(cover, MAX_COVER_WIDTH, MAX_COVER_HEIGHT))
                                using (MemoryStream result = new MemoryStream())
                                {
                                    resized.Save(result, ImageFormat.Jpeg);
                                    MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, result.ToArray());
                                }
                    }
                    // Decoding of invalid image data can fail, but main MediaItem is correct.
                    catch { }
                }
                else
                {
                    // In quick mode only allow thumbs taken from cache.
                    bool cachedOnly = forceQuickMode;

                    // Thumbnail extraction
                    fileName = mediaItemAccessor.ResourcePathName;
                    IThumbnailGenerator generator = ServiceRegistration.Get <IThumbnailGenerator>();
                    byte[]    thumbData;
                    ImageType imageType;
                    if (generator.GetThumbnail(fileName, 256, 256, cachedOnly, out thumbData, out imageType))
                    {
                        MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, thumbData);
                    }
                }
                return(true);
            }
            catch (Exception e)
            {
                // Only log at the info level here - And simply return false. This makes the importer know that we
                // couldn't perform our task here
                ServiceRegistration.Get <ILogger>().Info("BassAudioMetadataExtractor: Exception reading resource '{0}' (Text: '{1}')", fsra.CanonicalLocalResourcePath, e.Message);
            }
            return(false);
        }
コード例 #20
0
    public MediaItem QueryMediaItem()
    {
      ISQLDatabase database = ServiceRegistration.Get<ISQLDatabase>();
      ITransaction transaction = database.BeginTransaction();
      try
      {
        MediaItem result = null;

        // 1. Main query
        MainQueryBuilder mainQueryBuilder = new MainQueryBuilder(_miaManagement,
            _mainSelectAttributes.Values, null, _necessaryRequestedMIAs, _optionalRequestedMIAs, _filter, _sortInformation);

        using (IDbCommand mainQueryCommand = transaction.CreateCommand())
        {
          string mediaItemIdAlias2;
          IDictionary<MediaItemAspectMetadata, string> miamAliases;
          // Maps (selected and filtered) QueryAttributes to CompiledQueryAttributes in the SQL query
          IDictionary<QueryAttribute, string> qa2a;
          string statementStr;
          IList<BindVar> bindVars;
          mainQueryBuilder.GenerateSqlStatement(out mediaItemIdAlias2, out miamAliases, out qa2a,
              out statementStr, out bindVars);
          mainQueryCommand.CommandText = statementStr;
          foreach (BindVar bindVar in bindVars)
            database.AddParameter(mainQueryCommand, bindVar.Name, bindVar.Value, bindVar.VariableType);

          IEnumerable<MediaItemAspectMetadata> selectedMIAs = _necessaryRequestedMIAs.Union(_optionalRequestedMIAs);

          using (IDataReader mainReader = mainQueryCommand.ExecuteReader())
          {
            if (mainReader.Read())
            {
              Guid mediaItemId = database.ReadDBValue<Guid>(mainReader, mainReader.GetOrdinal(mediaItemIdAlias2));
              result = new MediaItem(mediaItemId);

              // Request complex attributes using media item ID
              IFilter modifiedFilter = BooleanCombinationFilter.CombineFilters(BooleanOperator.And, _filter, new MediaItemIdFilter(mediaItemId));
              IDictionary<MediaItemAspectMetadata.AttributeSpecification, ICollection<object>> complexAttributeValues =
                  new Dictionary<MediaItemAspectMetadata.AttributeSpecification, ICollection<object>>();
              foreach (MediaItemAspectMetadata.AttributeSpecification attr in _explicitSelectAttributes)
              {
                ComplexAttributeQueryBuilder complexAttributeQueryBuilder = new ComplexAttributeQueryBuilder(
                    _miaManagement, attr, null, null, modifiedFilter);
                using (IDbCommand complexQueryCommand = transaction.CreateCommand())
                {
                  string mediaItemIdAlias;
                  string valueAlias;
                  complexAttributeQueryBuilder.GenerateSqlStatement(out mediaItemIdAlias, out valueAlias,
                      out statementStr, out bindVars);
                  complexQueryCommand.CommandText = statementStr;
                  foreach (BindVar bindVar in bindVars)
                    database.AddParameter(complexQueryCommand, bindVar.Name, bindVar.Value, bindVar.VariableType);

                  Type valueType = attr.AttributeType;
                  using (IDataReader reader = complexQueryCommand.ExecuteReader())
                  {
                    if (reader.Read())
                    {
                      object value = database.ReadDBValue(valueType, reader, reader.GetOrdinal(valueAlias));
                      ICollection<object> attrValues;
                      if (!complexAttributeValues.TryGetValue(attr, out attrValues))
                        attrValues = complexAttributeValues[attr] = new List<object>();
                      attrValues.Add(value);
                    }
                  }
                }
              }

              // Put together all attributes
              foreach (MediaItemAspectMetadata miam in selectedMIAs)
              {
                if (mainReader.IsDBNull(mainReader.GetOrdinal(miamAliases[miam])))
                  // MIAM is not available for current media item
                  continue;
                MediaItemAspect mia = new MediaItemAspect(miam);
                foreach (MediaItemAspectMetadata.AttributeSpecification attr in miam.AttributeSpecifications.Values)
                  if (attr.Cardinality == Cardinality.Inline)
                  {
                    QueryAttribute qa = _mainSelectAttributes[attr];
                    string alias = qa2a[qa];
                    mia.SetAttribute(attr, database.ReadDBValue(attr.AttributeType, mainReader, mainReader.GetOrdinal(alias)));
                  }
                  else
                  {
                    ICollection<object> attrValues;
                    if (complexAttributeValues.TryGetValue(attr, out attrValues))
                      mia.SetCollectionAttribute(attr, attrValues);
                  }
                result.Aspects[miam.AspectId] = mia;
              }
            }
            return result;
          }
        }
      }
      finally
      {
        transaction.Dispose();
      }
    }
コード例 #21
0
        private bool ExtractThumbnail(ILocalFsResourceAccessor lfsra, IDictionary <Guid, MediaItemAspect> extractedAspectData)
        {
            // We can only work on files and make sure this file was detected by a lower MDE before (title is set then).
            // VideoAspect must be present to be sure it is actually a video resource.
            if (!lfsra.IsFile || !extractedAspectData.ContainsKey(VideoAspect.ASPECT_ID))
            {
                return(false);
            }

            byte[] thumb;
            // We only want to create missing thumbnails here, so check for existing ones first
            if (MediaItemAspect.TryGetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, out thumb) && thumb != null)
            {
                return(true);
            }

            // Check for a reasonable time offset
            long defaultVideoOffset = 720;
            long videoDuration;

            if (MediaItemAspect.TryGetAttribute(extractedAspectData, VideoAspect.ATTR_DURATION, out videoDuration))
            {
                if (defaultVideoOffset > videoDuration * 1 / 3)
                {
                    defaultVideoOffset = videoDuration * 1 / 3;
                }
            }

            // ToDo: Move creation of temp file names to FileUtils class
            string tempFileName = Path.GetTempPath() + Guid.NewGuid() + ".jpg";
            string executable   = FileUtils.BuildAssemblyRelativePath("ffmpeg.exe");
            string arguments    = string.Format("-ss {0} -i \"{1}\" -vframes 1 -an -dn -vf \"yadif='mode=send_frame:parity=auto:deint=all',scale=iw*sar:ih,setsar=1/1,scale=iw/2:-1\" -y \"{2}\"",
                                                defaultVideoOffset,
                                                // Calling EnsureLocalFileSystemAccess not necessary; access for external process ensured by ExecuteWithResourceAccess
                                                lfsra.LocalFileSystemPath,
                                                tempFileName);

            try
            {
                bool success;
                lock (FFMPEG_THROTTLE_LOCK)
                    success = lfsra.ExecuteWithResourceAccessAsync(executable, arguments, ProcessPriorityClass.Idle, PROCESS_TIMEOUT_MS).Result.Success;
                if (success && File.Exists(tempFileName))
                {
                    var binary = FileUtils.ReadFile(tempFileName);
                    MediaItemAspect.SetAttribute(extractedAspectData, ThumbnailLargeAspect.ATTR_THUMBNAIL, binary);
                    // Calling EnsureLocalFileSystemAccess not necessary; only string operation
                    ServiceRegistration.Get <ILogger>().Info("VideoThumbnailer: Successfully created thumbnail for resource '{0}'", lfsra.LocalFileSystemPath);
                }
                else
                {
                    // Calling EnsureLocalFileSystemAccess not necessary; only string operation
                    ServiceRegistration.Get <ILogger>().Warn("VideoThumbnailer: Failed to create thumbnail for resource '{0}'", lfsra.LocalFileSystemPath);
                }
            }
            catch (AggregateException ae)
            {
                ae.Handle(e =>
                {
                    if (e is TaskCanceledException)
                    {
                        ServiceRegistration.Get <ILogger>().Warn("VideoThumbnailer.ExtractThumbnail: External process aborted due to timeout: Executable='{0}', Arguments='{1}', Timeout='{2}'", executable, arguments, PROCESS_TIMEOUT_MS);
                        return(true);
                    }
                    return(false);
                });
            }
            finally
            {
                if (File.Exists(tempFileName))
                {
                    File.Delete(tempFileName);
                }
            }
            return(true);
        }
コード例 #22
0
ファイル: TraktHandler.cs プロジェクト: nagyist/MediaPortal-2
        private int GetMovieTmdb(MediaItem currMediaItem)
        {
            int iValue;

            return(MediaItemAspect.TryGetAttribute(currMediaItem.Aspects, MovieAspect.ATTR_TMDB_ID, out iValue) ? iValue : 0);
        }
コード例 #23
0
        private static bool IsWatched(MediaItem mediaItem)
        {
            int playCount;

            return(MediaItemAspect.TryGetAttribute(mediaItem.Aspects, MediaAspect.ATTR_PLAYCOUNT, 0, out playCount) && playCount > 0);
        }
コード例 #24
0
ファイル: TraktHandler.cs プロジェクト: nagyist/MediaPortal-2
        private int GetSeriesTvdbId(MediaItem currMediaItem)
        {
            int value;

            return(MediaItemAspect.TryGetAttribute(currMediaItem.Aspects, SeriesAspect.ATTR_TVDB_ID, out value) ? value : 0);
        }
コード例 #25
0
        public override int Compare(MediaItem x, MediaItem y)
        {
            SingleMediaItemAspect audioAspectX;
            SingleMediaItemAspect audioAspectY;

            if (MediaItemAspect.TryGetAspect(x.Aspects, AudioAspect.Metadata, out audioAspectX) && MediaItemAspect.TryGetAspect(y.Aspects, AudioAspect.Metadata, out audioAspectY))
            {
                string albumX = (string)audioAspectX.GetAttributeValue(AudioAspect.ATTR_ALBUM);
                string albumY = (string)audioAspectY.GetAttributeValue(AudioAspect.ATTR_ALBUM);
                int    res    = string.Compare(albumX, albumY);
                if (res != 0)
                {
                    return(res);
                }
            }
            // Fallback if album comparison is equal: Compare by track
            return(base.Compare(x, y));
        }
コード例 #26
0
ファイル: TraktHandler.cs プロジェクト: nagyist/MediaPortal-2
        private string GetSeriesImdbId(MediaItem currMediaItem)
        {
            string value;

            return(MediaItemAspect.TryGetAttribute(currMediaItem.Aspects, SeriesAspect.ATTR_IMDB_ID, out value) ? value : null);
        }
コード例 #27
0
        public bool TryMerge(IDictionary <Guid, IList <MediaItemAspect> > extractedAspects, IDictionary <Guid, IList <MediaItemAspect> > existingAspects)
        {
            try
            {
                EpisodeInfo existing  = new EpisodeInfo();
                EpisodeInfo extracted = new EpisodeInfo();

                //Extracted aspects
                IList <MultipleMediaItemAspect> providerResourceAspects;
                if (!MediaItemAspect.TryGetAspects(extractedAspects, ProviderResourceAspect.Metadata, out providerResourceAspects))
                {
                    return(false);
                }

                //Existing aspects
                IList <MultipleMediaItemAspect> existingProviderResourceAspects;
                MediaItemAspect.TryGetAspects(existingAspects, ProviderResourceAspect.Metadata, out existingProviderResourceAspects);

                //Don't merge virtual resources
                if (!providerResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_VIRTUAL).Any())
                {
                    //Replace if existing is a virtual resource
                    if (existingProviderResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_VIRTUAL).Any())
                    {
                        //Don't allow merge of subtitles into virtual item
                        if (extractedAspects.ContainsKey(SubtitleAspect.ASPECT_ID) && !extractedAspects.ContainsKey(VideoStreamAspect.ASPECT_ID))
                        {
                            return(false);
                        }

                        MediaItemAspect.SetAttribute(existingAspects, MediaAspect.ATTR_ISVIRTUAL, false);
                        MediaItemAspect.SetAttribute(existingAspects, MediaAspect.ATTR_ISSTUB,
                                                     providerResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_STUB).Any());
                        var now = DateTime.Now;
                        MediaItemAspect.SetAttribute(existingAspects, ImporterAspect.ATTR_DATEADDED, now);
                        MediaItemAspect.SetAttribute(existingAspects, ImporterAspect.ATTR_LAST_IMPORT_DATE, now);
                        existingAspects.Remove(ProviderResourceAspect.ASPECT_ID);
                        foreach (Guid aspect in extractedAspects.Keys)
                        {
                            if (!existingAspects.ContainsKey(aspect))
                            {
                                existingAspects.Add(aspect, extractedAspects[aspect]);
                            }
                        }

                        existing.FromMetadata(existingAspects);
                        extracted.FromMetadata(extractedAspects);

                        existing.MergeWith(extracted, true);
                        existing.SetMetadata(existingAspects);
                        return(true);
                    }

                    //Merge
                    if (providerResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_STUB).Any())
                    {
                        if (providerResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_STUB).Any() ||
                            existingProviderResourceAspects.Where(p => p.GetAttributeValue <int>(ProviderResourceAspect.ATTR_TYPE) == ProviderResourceAspect.TYPE_STUB).Any())
                        {
                            MediaItemAspect.SetAttribute(existingAspects, MediaAspect.ATTR_ISVIRTUAL, false);
                            MediaItemAspect.SetAttribute(existingAspects, MediaAspect.ATTR_ISSTUB, true);
                            if (!ResourceAspectMerger.MergeVideoResourceAspects(extractedAspects, existingAspects))
                            {
                                return(false);
                            }
                        }
                    }
                }

                existing.FromMetadata(existingAspects);
                extracted.FromMetadata(extractedAspects);

                existing.MergeWith(extracted, true);
                existing.SetMetadata(existingAspects);
                if (!ResourceAspectMerger.MergeVideoResourceAspects(extractedAspects, existingAspects))
                {
                    return(false);
                }

                return(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("EpisodeMergeHandler: Exception merging resources (Text: '{0}')", e.Message);
                return(false);
            }
        }
コード例 #28
0
        public override int Compare(MediaItem item1, MediaItem item2)
        {
            SingleMediaItemAspect audioAspectX;
            SingleMediaItemAspect audioAspectY;

            if (MediaItemAspect.TryGetAspect(item1.Aspects, AudioAspect.Metadata, out audioAspectX) && MediaItemAspect.TryGetAspect(item2.Aspects, AudioAspect.Metadata, out audioAspectY))
            {
                bool compilationX = (bool)(audioAspectX.GetAttributeValue(AudioAspect.ATTR_COMPILATION) ?? false);
                bool compilationY = (bool)(audioAspectY.GetAttributeValue(AudioAspect.ATTR_COMPILATION) ?? false);
                return(compilationX.CompareTo(compilationY));
            }
            return(base.Compare(item1, item2));
        }
コード例 #29
0
        internal static WebTVShowBasic TVShowBasic(IOwinContext context, MediaItem item)
        {
            ISet <Guid> necessaryMIATypespisodes = new HashSet <Guid>();

            necessaryMIATypespisodes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypespisodes.Add(EpisodeAspect.ASPECT_ID);

            IFilter unwatchedEpisodeFilter = BooleanCombinationFilter.CombineFilters(BooleanOperator.And,
                                                                                     new RelationshipFilter(EpisodeAspect.ROLE_EPISODE, SeriesAspect.ROLE_SERIES, item.MediaItemId),
                                                                                     new RelationalUserDataFilter(Guid.Empty, UserDataKeysKnown.KEY_PLAY_PERCENTAGE, RelationalOperator.LT,
                                                                                                                  UserDataKeysKnown.GetSortablePlayPercentageString(100), true));

            int unwatchedCount = MediaLibraryAccess.CountMediaItems(context, necessaryMIATypespisodes, unwatchedEpisodeFilter);

            var              mediaAspect    = item.GetAspect(MediaAspect.Metadata);
            var              seriesAspect   = item.GetAspect(SeriesAspect.Metadata);
            var              importerAspect = item.GetAspect(ImporterAspect.Metadata);
            DateTime?        firstAired     = mediaAspect.GetAttributeValue <DateTime?>(MediaAspect.ATTR_RECORDINGTIME);
            IList <WebActor> actors         = seriesAspect.GetCollectionAttribute <string>(SeriesAspect.ATTR_ACTORS)?.Distinct().Select(a => new WebActor(a)).ToList() ?? new List <WebActor>();
            WebArtwork       aw             = new WebArtwork();

            var show = new WebTVShowBasic()
            {
                Id                    = item.MediaItemId.ToString(),
                Title                 = seriesAspect.GetAttributeValue <string>(SeriesAspect.ATTR_SERIES_NAME),
                DateAdded             = importerAspect.GetAttributeValue <DateTime>(ImporterAspect.ATTR_DATEADDED),
                EpisodeCount          = seriesAspect.GetAttributeValue <int>(SeriesAspect.ATTR_AVAILABLE_EPISODES),
                SeasonCount           = seriesAspect.GetAttributeValue <int>(SeriesAspect.ATTR_AVAILABLE_SEASONS),
                Rating                = Convert.ToSingle(seriesAspect.GetAttributeValue <double>(SeriesAspect.ATTR_TOTAL_RATING)),
                ContentRating         = seriesAspect.GetAttributeValue <string>(SeriesAspect.ATTR_CERTIFICATION),
                Actors                = actors,
                UnwatchedEpisodeCount = unwatchedCount,
                Year                  = firstAired.HasValue ? firstAired.Value.Year : 0,
            };

            IList <MediaItemAspect> genres;

            if (item.Aspects.TryGetValue(GenreAspect.ASPECT_ID, out genres))
            {
                show.Genres = genres.Select(g => g.GetAttributeValue <string>(GenreAspect.ATTR_GENRE)).ToList();
            }

            string tvDbId;

            MediaItemAspect.TryGetExternalAttribute(item.Aspects, ExternalIdentifierAspect.SOURCE_TVDB, ExternalIdentifierAspect.TYPE_SERIES, out tvDbId);
            if (tvDbId != null)
            {
                show.ExternalId.Add(new WebExternalId {
                    Site = "TVDB", Id = tvDbId
                });
            }
            string imdbId;

            MediaItemAspect.TryGetExternalAttribute(item.Aspects, ExternalIdentifierAspect.SOURCE_IMDB, ExternalIdentifierAspect.TYPE_SERIES, out imdbId);
            if (imdbId != null)
            {
                show.ExternalId.Add(new WebExternalId {
                    Site = "IMDB", Id = imdbId
                });
            }

            return(show);
        }
コード例 #30
0
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary <Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            try
            {
                IFileSystemResourceAccessor fsra = mediaItemAccessor as IFileSystemResourceAccessor;
                if (fsra == null || !fsra.IsFile)
                {
                    return(false);
                }

                string title;
                if (!MediaItemAspect.TryGetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, out title) || string.IsNullOrEmpty(title))
                {
                    return(false);
                }

                string filePath       = mediaItemAccessor.CanonicalLocalResourcePath.ToString();
                string lowerExtension = StringUtils.TrimToEmpty(ProviderPathHelper.GetExtension(filePath)).ToLowerInvariant();
                if (lowerExtension != ".ts")
                {
                    return(false);
                }
                string            metaFilePath = ProviderPathHelper.ChangeExtension(filePath, ".xml");
                IResourceAccessor metaFileAccessor;
                if (!ResourcePath.Deserialize(metaFilePath).TryCreateLocalResourceAccessor(out metaFileAccessor))
                {
                    return(false);
                }

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

                // Handle series information
                SeriesInfo seriesInfo = GetSeriesFromTags(tags);
                if (seriesInfo.IsCompleteMatch)
                {
                    if (!forceQuickMode)
                    {
                        SeriesTvDbMatcher.Instance.FindAndUpdateSeries(seriesInfo);
                    }

                    seriesInfo.SetMetadata(extractedAspectData);
                }

                string value;
                if (TryGet(tags, TAG_TITLE, out value) && !string.IsNullOrEmpty(value))
                {
                    MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, value);
                }

                if (TryGet(tags, TAG_GENRE, out value))
                {
                    MediaItemAspect.SetCollectionAttribute(extractedAspectData, VideoAspect.ATTR_GENRES, new List <String> {
                        value
                    });
                }

                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_CHANNEL, out value))
                {
                    MediaItemAspect.SetAttribute(extractedAspectData, RecordingAspect.ATTR_CHANNEL, value);
                }

                // Recording date formatted: 2011-11-04 20:55
                DateTime recordingStart;
                DateTime recordingEnd;
                if (TryGet(tags, TAG_STARTTIME, out value) && DateTime.TryParse(value, out recordingStart))
                {
                    MediaItemAspect.SetAttribute(extractedAspectData, RecordingAspect.ATTR_STARTTIME, recordingStart);
                }

                if (TryGet(tags, TAG_ENDTIME, out value) && DateTime.TryParse(value, out recordingEnd))
                {
                    MediaItemAspect.SetAttribute(extractedAspectData, RecordingAspect.ATTR_ENDTIME, recordingEnd);
                }

                return(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(false);
        }
コード例 #31
0
        /// <summary>
        /// Gets a list of <see cref="FanArtImage"/>s for a requested <paramref name="mediaType"/>, <paramref name="fanArtType"/> and <paramref name="name"/>.
        /// The name can be: Series name, Actor name, Artist name depending on the <paramref name="mediaType"/>.
        /// </summary>
        /// <param name="mediaType">Requested FanArtMediaType</param>
        /// <param name="fanArtType">Requested FanArtType</param>
        /// <param name="name">Requested name of Series, Actor, Artist...</param>
        /// <param name="maxWidth">Maximum width for image. <c>0</c> returns image in original size.</param>
        /// <param name="maxHeight">Maximum height for image. <c>0</c> returns image in original size.</param>
        /// <param name="singleRandom">If <c>true</c> only one random image URI will be returned</param>
        /// <param name="result">Result if return code is <c>true</c>.</param>
        /// <returns><c>true</c> if at least one match was found.</returns>
        public bool TryGetFanArt(string mediaType, string fanArtType, string name, int maxWidth, int maxHeight, bool singleRandom, out IList <IResourceLocator> result)
        {
            result = null;

            if (!VALID_MEDIA_TYPES.Contains(mediaType) || !VALID_FANART_TYPES.Contains(fanArtType))
            {
                return(false);
            }

            if (string.IsNullOrWhiteSpace(name))
            {
                return(false);
            }

            Guid mediaItemId;

            if (Guid.TryParse(name, out mediaItemId) == false)
            {
                return(false);
            }

            IFanArtCache fanArtCache = ServiceRegistration.Get <IFanArtCache>();

            List <string> fanArtFiles = new List <string>();

            fanArtFiles.AddRange(fanArtCache.GetFanArtFiles(mediaItemId, fanArtType));

            // Try fallback
            if (fanArtFiles.Count == 0 && (mediaType == FanArtMediaTypes.MovieCollection || mediaType == FanArtMediaTypes.Character))
            {
                IMediaLibrary mediaLibrary = ServiceRegistration.Get <IMediaLibrary>(false);
                if (mediaLibrary == null)
                {
                    return(false);
                }

                IFilter           filter = new MediaItemIdFilter(mediaItemId);
                IList <MediaItem> items  = mediaLibrary.Search(new MediaItemQuery(NECESSARY_MIAS, OPTIONAL_MIAS, filter), false, null, true);
                if (items == null || items.Count == 0)
                {
                    return(false);
                }

                MediaItem mediaItem = items.First();

                if (mediaType == FanArtMediaTypes.MovieCollection)
                {
                    if (mediaItem.Aspects.ContainsKey(MovieCollectionAspect.ASPECT_ID))
                    {
                        IList <MultipleMediaItemAspect> relationAspects;
                        if (MediaItemAspect.TryGetAspects(mediaItem.Aspects, RelationshipAspect.Metadata, out relationAspects))
                        {
                            foreach (MultipleMediaItemAspect relation in relationAspects)
                            {
                                if ((Guid?)relation[RelationshipAspect.ATTR_LINKED_ROLE] == MovieAspect.ROLE_MOVIE)
                                {
                                    fanArtFiles.AddRange(fanArtCache.GetFanArtFiles((Guid)relation[RelationshipAspect.ATTR_LINKED_ID], fanArtType));
                                    if (fanArtFiles.Count > 0)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                else if (mediaType == FanArtMediaTypes.Character)
                {
                    if (mediaItem.Aspects.ContainsKey(CharacterAspect.ASPECT_ID))
                    {
                        IList <MultipleMediaItemAspect> relationAspects;
                        if (MediaItemAspect.TryGetAspects(mediaItem.Aspects, RelationshipAspect.Metadata, out relationAspects))
                        {
                            foreach (MultipleMediaItemAspect relation in relationAspects)
                            {
                                if ((Guid?)relation[RelationshipAspect.ATTR_LINKED_ROLE] == PersonAspect.ROLE_ACTOR)
                                {
                                    fanArtFiles.AddRange(fanArtCache.GetFanArtFiles((Guid)relation[RelationshipAspect.ATTR_LINKED_ID], fanArtType));
                                    if (fanArtFiles.Count > 0)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            List <IResourceLocator> files = new List <IResourceLocator>();

            try
            {
                files.AddRange(fanArtFiles
                               .Select(fileName => new ResourceLocator(ResourcePath.BuildBaseProviderPath(LocalFsResourceProviderBase.LOCAL_FS_RESOURCE_PROVIDER_ID, fileName)))
                               );
                result = files;
                return(result.Count > 0);
            }
            catch (Exception) { }
            return(false);
        }
コード例 #32
0
ファイル: MediaLibrary.cs プロジェクト: davinx/MediaPortal-2
    public Guid AddOrUpdateMediaItem(Guid parentDirectoryId, string systemId, ResourcePath path, IEnumerable<MediaItemAspect> mediaItemAspects)
    {
      // TODO: Avoid multiple write operations to the same media item
      ISQLDatabase database = ServiceRegistration.Get<ISQLDatabase>();
      ITransaction transaction = database.BeginTransaction();
      try
      {
        Guid? mediaItemId = GetMediaItemId(transaction, systemId, path);
        DateTime now = DateTime.Now;
        MediaItemAspect importerAspect;
        bool wasCreated = !mediaItemId.HasValue;
        if (wasCreated)
        {
          mediaItemId = AddMediaItem(database, transaction);

          MediaItemAspect pra = new MediaItemAspect(ProviderResourceAspect.Metadata);
          pra.SetAttribute(ProviderResourceAspect.ATTR_SYSTEM_ID, systemId);
          pra.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH, path.Serialize());
          pra.SetAttribute(ProviderResourceAspect.ATTR_PARENT_DIRECTORY_ID, parentDirectoryId);
          _miaManagement.AddOrUpdateMIA(transaction, mediaItemId.Value, pra, true);

          importerAspect = new MediaItemAspect(ImporterAspect.Metadata);
          importerAspect.SetAttribute(ImporterAspect.ATTR_DATEADDED, now);
        }
        else
          importerAspect = _miaManagement.GetMediaItemAspect(transaction, mediaItemId.Value, ImporterAspect.ASPECT_ID);
        importerAspect.SetAttribute(ImporterAspect.ATTR_DIRTY, false);
        importerAspect.SetAttribute(ImporterAspect.ATTR_LAST_IMPORT_DATE, now);

        _miaManagement.AddOrUpdateMIA(transaction, mediaItemId.Value, importerAspect, wasCreated);

        // Update
        foreach (MediaItemAspect mia in mediaItemAspects)
        {
          if (!_miaManagement.ManagedMediaItemAspectTypes.ContainsKey(mia.Metadata.AspectId))
            // Simply skip unknown MIA types. All types should have been added before import.
            continue;
          if (mia.Metadata.AspectId == ImporterAspect.ASPECT_ID ||
              mia.Metadata.AspectId == ProviderResourceAspect.ASPECT_ID)
          { // Those aspects are managed by the MediaLibrary
            ServiceRegistration.Get<ILogger>().Warn("MediaLibrary.AddOrUpdateMediaItem: Client tried to update either ImporterAspect or ProviderResourceAspect");
            continue;
          }
          if (wasCreated)
            _miaManagement.AddOrUpdateMIA(transaction, mediaItemId.Value, mia, true);
          else
            _miaManagement.AddOrUpdateMIA(transaction, mediaItemId.Value, mia);
        }
        transaction.Commit();
        return mediaItemId.Value;
      }
      catch (Exception e)
      {
        ServiceRegistration.Get<ILogger>().Error("MediaLibrary: Error adding or updating media item(s) in path '{0}'", e, path.Serialize());
        transaction.Rollback();
        throw;
      }
    }
コード例 #33
0
        protected override void Update()
        {
            if (_updating)
            {
                return;
            }
            _updating = true;
            try
            {
                IPlayerContextManager playerContextManager = ServiceRegistration.Get <IPlayerContextManager>();
                IPlayerContext        playerContext        = playerContextManager.GetPlayerContext(_playerContext);

                _currentMediaItem = playerContext == null ? null : playerContext.CurrentMediaItem;
                SingleMediaItemAspect imageAspect;
                if (_currentMediaItem == null || !MediaItemAspect.TryGetAspect(_currentMediaItem.Aspects, ImageAspect.Metadata, out imageAspect))
                {
                    imageAspect = null;
                }

                if (imageAspect == null)
                {
                    ImageDimensions   = string.Empty;
                    CameraMake        = string.Empty;
                    CameraModel       = string.Empty;
                    ImageISOSpeed     = string.Empty;
                    ImageExposureTime = string.Empty;
                    ImageFNumber      = string.Empty;
                    ImageFlashMode    = string.Empty;
                    ImageMeteringMode = string.Empty;
                    Country           = string.Empty;
                    State             = string.Empty;
                    City = string.Empty;
                }
                else
                {
                    var mpc = playerContext != null ?playerContext.CurrentPlayer as IMediaPlaybackControl : null;
                    if (mpc != null)
                    {
                        TransitionDuration = mpc.IsPaused ? 0.1d : 2.0d;
                    }
                    ImageDimensions   = String.Format("{0} x {1}", imageAspect[ImageAspect.ATTR_WIDTH], imageAspect[ImageAspect.ATTR_HEIGHT]);
                    CameraMake        = (string)imageAspect[ImageAspect.ATTR_MAKE];
                    CameraModel       = (string)imageAspect[ImageAspect.ATTR_MODEL];
                    ImageISOSpeed     = (string)imageAspect[ImageAspect.ATTR_ISO_SPEED];
                    ImageExposureTime = (string)imageAspect[ImageAspect.ATTR_EXPOSURE_TIME];
                    ImageFNumber      = (string)imageAspect[ImageAspect.ATTR_FNUMBER];
                    ImageFlashMode    = (string)imageAspect[ImageAspect.ATTR_FLASH_MODE];
                    ImageMeteringMode = (string)imageAspect[ImageAspect.ATTR_METERING_MODE];
                    Country           = (string)imageAspect[ImageAspect.ATTR_COUNTRY];
                    State             = (string)imageAspect[ImageAspect.ATTR_STATE];
                    City = (string)imageAspect[ImageAspect.ATTR_CITY];
                }
            }
            catch (Exception e)
            {
                ServiceRegistration.Get <ILogger>().Warn("ImagePlayerUIContributor: Error updating properties", e);
            }
            finally
            {
                _updating = false;
            }
        }
コード例 #34
0
 protected int CompareDifferentTypes(MediaItemAspect aspectX, MediaItemAspect aspectY)
 {
   return aspectX != null ? 1 : -1;
 }
コード例 #35
0
        /// <summary>
        /// Gets a list of <see cref="FanArtImage"/>s for a requested <paramref name="mediaType"/>, <paramref name="fanArtType"/> and <paramref name="name"/>.
        /// The name can be: Series name, Actor name, Artist name depending on the <paramref name="mediaType"/>.
        /// </summary>
        /// <param name="mediaType">Requested FanArtMediaType</param>
        /// <param name="fanArtType">Requested FanArtType</param>
        /// <param name="name">Requested name of Series, Actor, Artist...</param>
        /// <param name="maxWidth">Maximum width for image. <c>0</c> returns image in original size.</param>
        /// <param name="maxHeight">Maximum height for image. <c>0</c> returns image in original size.</param>
        /// <param name="singleRandom">If <c>true</c> only one random image URI will be returned</param>
        /// <param name="result">Result if return code is <c>true</c>.</param>
        /// <returns><c>true</c> if at least one match was found.</returns>
        public bool TryGetFanArt(string mediaType, string fanArtType, string name, int maxWidth, int maxHeight, bool singleRandom, out IList <IResourceLocator> result)
        {
            result = null;
            Guid mediaItemId;

            if (mediaType != FanArtMediaTypes.Actor || (fanArtType != FanArtTypes.Undefined && fanArtType != FanArtTypes.Thumbnail))
            {
                return(false);
            }

            // Don't try to load "fanart" for images
            if (!Guid.TryParse(name, out mediaItemId))
            {
                return(false);
            }

            IMediaLibrary mediaLibrary = ServiceRegistration.Get <IMediaLibrary>(false);

            if (mediaLibrary == null)
            {
                return(false);
            }

            IFilter           filter        = new RelationshipFilter(MovieAspect.ROLE_MOVIE, PersonAspect.ROLE_ACTOR, mediaItemId);
            IList <MediaItem> items         = null;
            List <Guid>       necessaryMias = new List <Guid>(NECESSARY_MIAS);
            MediaItemQuery    mediaQuery    = new MediaItemQuery(necessaryMias, filter);

            mediaQuery.Limit = 1;
            items            = mediaLibrary.Search(mediaQuery, false, null, false);
            if (items == null || items.Count == 0)
            {
                return(false);
            }

            MediaItem mediaItem = items.First();

            // Virtual resources won't have any local fanart
            if (mediaItem.IsVirtual)
            {
                return(false);
            }
            var mediaIteamLocator = mediaItem.GetResourceLocator();
            var fanArtPaths       = new List <ResourcePath>();
            var files             = new List <IResourceLocator>();

            string actorName = null;
            SingleMediaItemAspect videoAspect;
            List <string>         actors = new List <string>();

            if (MediaItemAspect.TryGetAspect(mediaItem.Aspects, VideoAspect.Metadata, out videoAspect))
            {
                IEnumerable <object> actorObjects = videoAspect.GetCollectionAttribute <object>(VideoAspect.ATTR_ACTORS);
                if (actorObjects != null)
                {
                    actors.AddRange(actorObjects.Cast <string>());
                }
            }

            IList <MultipleMediaItemAspect> relationAspects;

            if (MediaItemAspect.TryGetAspects(mediaItem.Aspects, RelationshipAspect.Metadata, out relationAspects))
            {
                foreach (MultipleMediaItemAspect relation in relationAspects)
                {
                    if ((Guid?)relation[RelationshipAspect.ATTR_LINKED_ROLE] == PersonAspect.ROLE_ACTOR && (Guid?)relation[RelationshipAspect.ATTR_LINKED_ID] == mediaItemId)
                    {
                        int?index = (int?)relation[RelationshipAspect.ATTR_RELATIONSHIP_INDEX];
                        if (index.HasValue && actors.Count > index.Value && index.Value >= 0)
                        {
                            actorName = actors[index.Value];
                        }
                        break;
                    }
                }
            }

            // File based access
            try
            {
                var mediaItemPath          = mediaIteamLocator.NativeResourcePath;
                var mediaItemDirectoryPath = ResourcePathHelper.Combine(mediaItemPath, "../");

                if (!string.IsNullOrEmpty(actorName))
                {
                    using (var directoryRa = new ResourceLocator(mediaIteamLocator.NativeSystemId, mediaItemDirectoryPath).CreateAccessor())
                    {
                        var directoryFsra = directoryRa as IFileSystemResourceAccessor;
                        if (directoryFsra != null)
                        {
                            //Get Artists thumbs
                            IFileSystemResourceAccessor actorMediaItemDirectory = directoryFsra.GetResource(".actors");
                            if (actorMediaItemDirectory != null)
                            {
                                var potentialArtistFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(actorMediaItemDirectory);

                                foreach (ResourcePath thumbPath in
                                         from potentialFanArtFile in potentialArtistFanArtFiles
                                         let potentialFanArtFileNameWithoutExtension = ResourcePathHelper.GetFileNameWithoutExtension(potentialFanArtFile.ToString())
                                                                                       where potentialFanArtFileNameWithoutExtension.StartsWith(actorName.Replace(" ", "_"), StringComparison.InvariantCultureIgnoreCase)
                                                                                       select potentialFanArtFile)
                                {
                                    files.Add(new ResourceLocator(mediaIteamLocator.NativeSystemId, thumbPath));
                                }
                            }
                        }
                    }

                    //Find central actor information folder
                    ResourcePath centralActorFolderPath = LocalFanartHelper.GetCentralPersonFolder(mediaItemDirectoryPath, CentralPersonFolderType.MovieActors);
                    if (centralActorFolderPath != null)
                    {
                        // First get the ResourcePath of the central directory
                        var actorFolderPath = ResourcePathHelper.Combine(centralActorFolderPath, $"{LocalFanartHelper.GetSafePersonFolderName(actorName)}/");

                        // Then try to create an IFileSystemResourceAccessor for this directory
                        actorFolderPath.TryCreateLocalResourceAccessor(out var artistNfoDirectoryRa);
                        var directoryFsra = artistNfoDirectoryRa as IFileSystemResourceAccessor;
                        if (directoryFsra != null)
                        {
                            var potentialFanArtFiles = LocalFanartHelper.GetPotentialFanArtFiles(directoryFsra);

                            if (fanArtType == FanArtTypes.Poster || fanArtType == FanArtTypes.Thumbnail)
                            {
                                fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.ARTIST_FILENAMES));
                                fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.POSTER_FILENAMES));
                                fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.THUMB_FILENAMES));
                            }

                            if (fanArtType == FanArtTypes.Banner)
                            {
                                fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.BANNER_FILENAMES));
                            }

                            if (fanArtType == FanArtTypes.Logo)
                            {
                                fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.LOGO_FILENAMES));
                            }

                            if (fanArtType == FanArtTypes.ClearArt)
                            {
                                fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.CLEARART_FILENAMES));
                            }

                            if (fanArtType == FanArtTypes.FanArt)
                            {
                                fanArtPaths.AddRange(LocalFanartHelper.FilterPotentialFanArtFilesByPrefix(potentialFanArtFiles, LocalFanartHelper.BACKDROP_FILENAMES));

                                if (directoryFsra.ResourceExists("ExtraFanArt/"))
                                {
                                    using (var extraFanArtDirectoryFsra = directoryFsra.GetResource("ExtraFanArt/"))
                                        fanArtPaths.AddRange(LocalFanartHelper.GetPotentialFanArtFiles(extraFanArtDirectoryFsra));
                                }
                            }

                            files.AddRange(fanArtPaths.Select(path => new ResourceLocator(mediaIteamLocator.NativeSystemId, path)));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
#if DEBUG
                ServiceRegistration.Get <ILogger>().Warn("LocalMovieActorFanArtProvider: Error while searching fanart of type '{0}' for '{1}'", ex, fanArtType, mediaIteamLocator);
#endif
            }
            result = files;
            return(files.Count > 0);
        }
コード例 #36
0
    public MediaItemAspect GetMediaItemAspect(ITransaction transaction, Guid mediaItemId, Guid aspectId)
    {
      MediaItemAspectMetadata miaType;
      if (!_managedMIATypes.TryGetValue(aspectId, out miaType) || miaType == null)
        throw new ArgumentException(string.Format("MIA_Management: Requested media item aspect type with id '{0}' doesn't exist", aspectId));

      MediaItemAspect result = new MediaItemAspect(miaType);

      Namespace ns = new Namespace();
      string miaTableName = GetMIATableName(miaType);
      IList<string> terms = new List<string>();
      foreach (MediaItemAspectMetadata.AttributeSpecification spec in miaType.AttributeSpecifications.Values)
      {
        switch (spec.Cardinality)
        {
          case Cardinality.Inline:
            string attrName = GetMIAAttributeColumnName(spec);
            terms.Add(attrName + " " + ns.GetOrCreate(spec, "A"));
            break;
          case Cardinality.OneToMany:
            result.SetCollectionAttribute(spec, GetOneToManyMIAAttributeValues(transaction, mediaItemId, spec));
            break;
          case Cardinality.ManyToOne:
            object value = GetManyToOneMIAAttributeValue(transaction, mediaItemId, spec, miaTableName);
            if (!AttributeIsEmpty(value))
              result.SetAttribute(spec, value);
            break;
          case Cardinality.ManyToMany:
            result.SetCollectionAttribute(spec, GetManyToManyMIAAttributeValues(transaction, mediaItemId, spec));
            break;
          default:
            throw new NotImplementedException(string.Format("Cardinality '{0}' for attribute '{1}.{2}' is not implemented",
                spec.Cardinality, miaType.AspectId, spec.AttributeName));
        }
      }
      StringBuilder mainQueryBuilder = new StringBuilder("SELECT ");
      mainQueryBuilder.Append(StringUtils.Join(", ", terms));
      mainQueryBuilder.Append(" FROM ");
      mainQueryBuilder.Append(miaTableName);
      mainQueryBuilder.Append(" WHERE ");
      mainQueryBuilder.Append(MIA_MEDIA_ITEM_ID_COL_NAME);
      mainQueryBuilder.Append(" = @MEDIA_ITEM_ID");

      ISQLDatabase database = transaction.Database;
      using (IDbCommand command = transaction.CreateCommand())
      {
        command.CommandText = mainQueryBuilder.ToString();

        database.AddParameter(command, "MEDIA_ITEM_ID", mediaItemId, typeof(Guid));

        using (IDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow))
        {
          int i = 0;
          if (reader.Read())
            foreach (MediaItemAspectMetadata.AttributeSpecification spec in miaType.AttributeSpecifications.Values)
            {
              if (spec.Cardinality == Cardinality.Inline)
              {
                object value = ReadObject(database, reader, i, spec);
                if (!AttributeIsEmpty(value))
                  result.SetAttribute(spec, value);
              }
              i++;
            }
        }
      }
      return result;
    }
コード例 #37
0
        public static MediaItemAspectMetadata.AttributeSpecification GetAttributeSpecification(MediaItem mediaItem, IEnumerable <MediaItemAspectMetadata.SingleAttributeSpecification> attributes, out MediaItemAspect aspect)
        {
            SingleMediaItemAspect singleAspect = null;

            MediaItemAspectMetadata.SingleAttributeSpecification attr = attributes.FirstOrDefault(a => MediaItemAspect.TryGetAspect(mediaItem.Aspects, a.ParentMIAM, out singleAspect));
            aspect = singleAspect;
            return(attr);
        }
コード例 #38
0
 /// <summary>
 /// Adds or updates the given media item aspect on the media item with the given id.
 /// </summary>
 /// <param name="transaction">Database transaction to use.</param>
 /// <param name="mediaItemId">Id of the media item to be added or updated.</param>
 /// <param name="mia">Media item aspect to write to DB.</param>
 public void AddOrUpdateMIA(ITransaction transaction, Guid mediaItemId, MediaItemAspect mia)
 {
   AddOrUpdateMIA(transaction, mediaItemId, mia, !MIAExists(transaction, mediaItemId, mia.Metadata.AspectId));
 }
コード例 #39
0
        public static MediaItemAspectMetadata.AttributeSpecification GetAttributeSpecification(MediaItem mediaItem, IEnumerable <MediaItemAspectMetadata.MultipleAttributeSpecification> attributes, out MediaItemAspect aspect)
        {
            IList <MultipleMediaItemAspect> multipleAspects = null;

            MediaItemAspectMetadata.MultipleAttributeSpecification attr = attributes.FirstOrDefault(a => MediaItemAspect.TryGetAspects(mediaItem.Aspects, a.ParentMIAM, out multipleAspects));
            aspect = attr != null ? multipleAspects[0] : null;
            return(attr);
        }
コード例 #40
0
    public IList<MediaItem> QueryList()
    {
      ISQLDatabase database = ServiceRegistration.Get<ISQLDatabase>();
      ITransaction transaction = database.BeginTransaction();
      try
      {
        string statementStr;
        IList<BindVar> bindVars;

        // 1. Request all complex attributes
        IDictionary<Guid, IDictionary<MediaItemAspectMetadata.AttributeSpecification, ICollection<object>>> complexAttributeValues =
            new Dictionary<Guid, IDictionary<MediaItemAspectMetadata.AttributeSpecification, ICollection<object>>>();
        foreach (MediaItemAspectMetadata.AttributeSpecification attr in _explicitSelectAttributes)
        {
          ComplexAttributeQueryBuilder complexAttributeQueryBuilder = new ComplexAttributeQueryBuilder(
              _miaManagement, attr, null, _necessaryRequestedMIAs, _filter);
          using (IDbCommand command = transaction.CreateCommand())
          {
            string mediaItemIdAlias;
            string valueAlias;
            complexAttributeQueryBuilder.GenerateSqlStatement(out mediaItemIdAlias, out valueAlias,
                out statementStr, out bindVars);
            command.CommandText = statementStr;
            foreach (BindVar bindVar in bindVars)
              database.AddParameter(command, bindVar.Name, bindVar.Value, bindVar.VariableType);

            Type valueType = attr.AttributeType;
            using (IDataReader reader = command.ExecuteReader())
            {
              while (reader.Read())
              {
                Guid mediaItemId = database.ReadDBValue<Guid>(reader, reader.GetOrdinal(mediaItemIdAlias));
                object value = database.ReadDBValue(valueType, reader, reader.GetOrdinal(valueAlias));
                IDictionary<MediaItemAspectMetadata.AttributeSpecification, ICollection<object>> attributeValues;
                if (!complexAttributeValues.TryGetValue(mediaItemId, out attributeValues))
                  attributeValues = complexAttributeValues[mediaItemId] =
                      new Dictionary<MediaItemAspectMetadata.AttributeSpecification, ICollection<object>>();
                ICollection<object> attrValues;
                if (!attributeValues.TryGetValue(attr, out attrValues))
                  attrValues = attributeValues[attr] = new List<object>();
                attrValues.Add(value);
              }
            }
          }
        }

        // 2. Main query
        MainQueryBuilder mainQueryBuilder = new MainQueryBuilder(_miaManagement,
            _mainSelectAttributes.Values, null, _necessaryRequestedMIAs, _optionalRequestedMIAs, _filter, _sortInformation);

        using (IDbCommand command = transaction.CreateCommand())
        {
          string mediaItemIdAlias2;
          IDictionary<MediaItemAspectMetadata, string> miamAliases;
          // Maps (selected and filtered) QueryAttributes to CompiledQueryAttributes in the SQL query
          IDictionary<QueryAttribute, string> qa2a;
          mainQueryBuilder.GenerateSqlStatement(out mediaItemIdAlias2, out miamAliases, out qa2a,
              out statementStr, out bindVars);
          command.CommandText = statementStr;
          foreach (BindVar bindVar in bindVars)
            database.AddParameter(command, bindVar.Name, bindVar.Value, bindVar.VariableType);

          IEnumerable<MediaItemAspectMetadata> selectedMIAs = _necessaryRequestedMIAs.Union(_optionalRequestedMIAs);

          ICollection<Guid> mediaItems = new HashSet<Guid>();
          using (IDataReader reader = command.ExecuteReader())
          {
            IList<MediaItem> result = new List<MediaItem>();
            while (reader.Read())
            {
              Guid mediaItemId = database.ReadDBValue<Guid>(reader, reader.GetOrdinal(mediaItemIdAlias2));
              if (mediaItems.Contains(mediaItemId))
                // Media item was already added to result - query results are not always unique because of JOINs used for filtering
                continue;
              mediaItems.Add(mediaItemId);
              IDictionary<MediaItemAspectMetadata.AttributeSpecification, ICollection<object>> attributeValues;
              if (!complexAttributeValues.TryGetValue(mediaItemId, out attributeValues))
                  attributeValues = null;
              MediaItem mediaItem = new MediaItem(mediaItemId);
              foreach (MediaItemAspectMetadata miam in selectedMIAs)
              {
                if (reader.IsDBNull(reader.GetOrdinal(miamAliases[miam])))
                  // MIAM is not available for current media item
                  continue;
                MediaItemAspect mia = new MediaItemAspect(miam);
                foreach (MediaItemAspectMetadata.AttributeSpecification attr in miam.AttributeSpecifications.Values)
                  if (attr.Cardinality == Cardinality.Inline)
                  {
                    QueryAttribute qa = _mainSelectAttributes[attr];
                    string alias = qa2a[qa];
                    mia.SetAttribute(attr, database.ReadDBValue(attr.AttributeType, reader, reader.GetOrdinal(alias)));
                  }
                  else
                  {
                    ICollection<object> attrValues;
                    if (attributeValues != null && attributeValues.TryGetValue(attr, out attrValues))
                      mia.SetCollectionAttribute(attr, attrValues);
                  }
                mediaItem.Aspects[miam.AspectId] = mia;
              }
              result.Add(mediaItem);
            }
            return result;
          }
        }
      }
      finally
      {
        transaction.Dispose();
      }
    }
コード例 #41
0
ファイル: TraktHandler.cs プロジェクト: nagyist/MediaPortal-2
        private string GetMovieImdb(MediaItem currMediaItem)
        {
            string value;

            return(MediaItemAspect.TryGetAttribute(currMediaItem.Aspects, MovieAspect.ATTR_IMDB_ID, out value) ? value : null);
        }
コード例 #42
0
        public bool TryExtractMetadata(IResourceAccessor mediaItemAccessor, IDictionary<Guid, MediaItemAspect> extractedAspectData, bool forceQuickMode)
        {
            try
              {
            IResourceAccessor ra = mediaItemAccessor.Clone();
            try
            {
              using (ILocalFsResourceAccessor fsra = StreamedResourceToLocalFsAccessBridge.GetLocalFsResourceAccessor(ra))
            if (fsra != null && fsra.IsDirectory && fsra.ResourceExists("BDMV"))
            {
              IFileSystemResourceAccessor fsraBDMV = fsra.GetResource("BDMV");
              if (fsraBDMV != null && fsraBDMV.ResourceExists("index.bdmv"))
              {
                // BluRay
                MediaItemAspect mediaAspect;
                if (!extractedAspectData.TryGetValue(MediaAspect.ASPECT_ID, out mediaAspect))
                  extractedAspectData[MediaAspect.ASPECT_ID] = mediaAspect = new MediaItemAspect(MediaAspect.Metadata);
                MediaItemAspect videoAspect;
                if (!extractedAspectData.TryGetValue(VideoAspect.ASPECT_ID, out videoAspect))
                  extractedAspectData[VideoAspect.ASPECT_ID] = new MediaItemAspect(VideoAspect.Metadata);

                mediaAspect.SetAttribute(MediaAspect.ATTR_MIME_TYPE, "video/bluray"); // BluRay disc

                string bdmvDirectory = fsra.LocalFileSystemPath;
                BDInfoExt bdinfo = new BDInfoExt(bdmvDirectory);
                mediaAspect.SetAttribute(MediaAspect.ATTR_TITLE, bdinfo.GetTitle() ?? mediaItemAccessor.ResourceName);
                return true;
              }
            }
            }
            catch
            {
              ra.Dispose();
              throw;
            }
            return false;
              }
              catch
              {
            // Only log at the info level here - And simply return false. This makes the importer know that we
            // couldn't perform our task here
            if (mediaItemAccessor != null)
              ServiceRegistration.Get<ILogger>().Info("BluRayMetadataExtractor: Exception reading source '{0}'", mediaItemAccessor.ResourcePathName);
            return false;
              }
        }
コード例 #43
0
        private async Task <bool> TryExtractStubItemsAsync(IResourceAccessor mediaItemAccessor, ICollection <IDictionary <Guid, IList <MediaItemAspect> > > extractedStubAspectData)
        {
            // Get a unique number for this call to TryExtractMetadataAsync. We use this to make reading the debug log easier.
            // This MetadataExtractor is called in parallel for multiple MediaItems so that the respective debug log entries
            // for one call are not contained one after another in debug log. We therefore prepend this number before every log entry.
            var miNumber = Interlocked.Increment(ref _lastMediaItemNumber);

            try
            {
                _debugLogger.Info("[#{0}]: Start extracting stubs for resource '{1}'", miNumber, mediaItemAccessor);

                if (!IsStubResource(mediaItemAccessor))
                {
                    _debugLogger.Info("[#{0}]: Cannot extract stubs; file does not have a supported extension", miNumber);
                    return(false);
                }

                // This MetadataExtractor only works for MediaItems accessible by an IFileSystemResourceAccessor.
                // Otherwise it is not possible to find a stub-file in the MediaItem's directory.
                if (!(mediaItemAccessor is IFileSystemResourceAccessor))
                {
                    _debugLogger.Info("[#{0}]: Cannot extract stubs; mediaItemAccessor is not an IFileSystemResourceAccessor", miNumber);
                    return(false);
                }

                var fsra            = mediaItemAccessor as IFileSystemResourceAccessor;
                var movieStubReader = new StubMovieReader(_debugLogger, miNumber, true, _settings);
                if (fsra != null && await movieStubReader.TryReadMetadataAsync(fsra).ConfigureAwait(false))
                {
                    MovieStub movie = movieStubReader.GetMovieStubs().FirstOrDefault();
                    if (movie != null)
                    {
                        Dictionary <Guid, IList <MediaItemAspect> > extractedAspectData = new Dictionary <Guid, IList <MediaItemAspect> >();

                        MultipleMediaItemAspect providerResourceAspect = MediaItemAspect.CreateAspect(extractedAspectData, ProviderResourceAspect.Metadata);
                        providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_INDEX, 0);
                        providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_TYPE, ProviderResourceAspect.TYPE_STUB);
                        providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH, fsra.CanonicalLocalResourcePath.Serialize());
                        if (IsVhs(mediaItemAccessor))
                        {
                            providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, "video/unknown");

                            MultipleMediaItemAspect videoStreamAspects = MediaItemAspect.CreateAspect(extractedAspectData, VideoStreamAspect.Metadata);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_STREAM_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_TYPE, VideoStreamAspect.TYPE_SD);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_ASPECTRATIO, Convert.ToSingle(4.0 / 3.0));
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_FPS, 25F);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_WIDTH, 720);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_HEIGHT, 576);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_AUDIOSTREAMCOUNT, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART_SET_NAME, "VHS Stub");

                            MultipleMediaItemAspect audioAspect = MediaItemAspect.CreateAspect(extractedAspectData, VideoAudioStreamAspect.Metadata);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_STREAM_INDEX, 1);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOCHANNELS, 2);
                        }
                        else if (IsTv(mediaItemAccessor))
                        {
                            providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, "video/unknown");

                            MultipleMediaItemAspect videoStreamAspects = MediaItemAspect.CreateAspect(extractedAspectData, VideoStreamAspect.Metadata);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_STREAM_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_TYPE, VideoStreamAspect.TYPE_HD);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_ASPECTRATIO, Convert.ToSingle(16.0 / 9.0));
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_FPS, 25F);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_WIDTH, 1920);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_HEIGHT, 1080);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_AUDIOSTREAMCOUNT, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART_SET_NAME, "TV Stub");

                            MultipleMediaItemAspect audioAspect = MediaItemAspect.CreateAspect(extractedAspectData, VideoAudioStreamAspect.Metadata);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_STREAM_INDEX, 1);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOCHANNELS, 2);
                        }
                        else if (IsDvd(mediaItemAccessor))
                        {
                            providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, "video/mp2t");

                            MultipleMediaItemAspect videoStreamAspects = MediaItemAspect.CreateAspect(extractedAspectData, VideoStreamAspect.Metadata);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_STREAM_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_TYPE, VideoStreamAspect.TYPE_SD);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_ASPECTRATIO, Convert.ToSingle(16.0 / 9.0));
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_FPS, 25F);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_WIDTH, 720);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_HEIGHT, 576);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEOENCODING, "MPEG-2 Video");
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_AUDIOSTREAMCOUNT, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART_SET_NAME, "DVD Stub");

                            MultipleMediaItemAspect audioAspect = MediaItemAspect.CreateAspect(extractedAspectData, VideoAudioStreamAspect.Metadata);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_STREAM_INDEX, 1);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOENCODING, "AC3");
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOCHANNELS, 6);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOSAMPLERATE, 48000L);
                        }
                        else if (IsBluray(mediaItemAccessor))
                        {
                            providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, "video/mp4");

                            MultipleMediaItemAspect videoStreamAspects = MediaItemAspect.CreateAspect(extractedAspectData, VideoStreamAspect.Metadata);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_STREAM_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_TYPE, VideoStreamAspect.TYPE_HD);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_ASPECTRATIO, Convert.ToSingle(16.0 / 9.0));
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_FPS, 24F);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_WIDTH, 1920);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_HEIGHT, 1080);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEOENCODING, "AVC");
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_AUDIOSTREAMCOUNT, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART_SET_NAME, "Bluray Stub");

                            MultipleMediaItemAspect audioAspect = MediaItemAspect.CreateAspect(extractedAspectData, VideoAudioStreamAspect.Metadata);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_STREAM_INDEX, 1);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOENCODING, "AC3");
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOCHANNELS, 6);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOSAMPLERATE, 48000L);
                        }
                        else if (IsHdDvd(mediaItemAccessor))
                        {
                            providerResourceAspect.SetAttribute(ProviderResourceAspect.ATTR_MIME_TYPE, "video/wvc1");

                            MultipleMediaItemAspect videoStreamAspects = MediaItemAspect.CreateAspect(extractedAspectData, VideoStreamAspect.Metadata);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_STREAM_INDEX, 0);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_TYPE, VideoStreamAspect.TYPE_HD);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_ASPECTRATIO, Convert.ToSingle(16.0 / 9.0));
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_FPS, 24F);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_WIDTH, 1920);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_HEIGHT, 1080);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEOENCODING, "VC1");
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_AUDIOSTREAMCOUNT, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART, 1);
                            videoStreamAspects.SetAttribute(VideoStreamAspect.ATTR_VIDEO_PART_SET_NAME, "HDDVD Stub");

                            MultipleMediaItemAspect audioAspect = MediaItemAspect.CreateAspect(extractedAspectData, VideoAudioStreamAspect.Metadata);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_RESOURCE_INDEX, 0);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_STREAM_INDEX, 1);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOENCODING, "AC3");
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOCHANNELS, 6);
                            audioAspect.SetAttribute(VideoAudioStreamAspect.ATTR_AUDIOSAMPLERATE, 48000L);
                        }

                        SingleMediaItemAspect videoAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, VideoAspect.Metadata);
                        videoAspect.SetAttribute(VideoAspect.ATTR_ISDVD, true);

                        SingleMediaItemAspect movieAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, MovieAspect.Metadata);
                        movieAspect.SetAttribute(MovieAspect.ATTR_MOVIE_NAME, movie.Title);

                        SingleMediaItemAspect stubAspect = MediaItemAspect.GetOrCreateAspect(extractedAspectData, StubAspect.Metadata);
                        stubAspect.SetAttribute(StubAspect.ATTR_DISC_NAME, movie.DiscName);
                        stubAspect.SetAttribute(StubAspect.ATTR_MESSAGE, movie.Message);

                        MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_TITLE, movie.Title);
                        MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_SORT_TITLE, BaseInfo.GetSortTitle(movie.Title));
                        MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_ISVIRTUAL, false);
                        MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_ISSTUB, true);
                        MediaItemAspect.SetAttribute(extractedAspectData, MediaAspect.ATTR_RECORDINGTIME, fsra.LastChanged);

                        extractedStubAspectData.Add(extractedAspectData);
                    }
                }
                else
                {
                    _debugLogger.Warn("[#{0}]: No valid metadata found in movie stub file", miNumber);
                }


                _debugLogger.Info("[#{0}]: Successfully finished extracting stubs", miNumber);
                return(true);
            }
            catch (Exception e)
            {
                ServiceRegistration.Get <ILogger>().Warn("StubMovieMetadataExtractor: Exception while extracting stubs for resource '{0}'; enable debug logging for more details.", mediaItemAccessor);
                _debugLogger.Error("[#{0}]: Exception while extracting stubs", e, miNumber);
                return(false);
            }
        }