Example #1
0
        private void AddMediaInfoTokens(Dictionary <string, Func <TokenMatch, string> > tokenHandlers, MovieFile movieFile)
        {
            if (movieFile.MediaInfo == null)
            {
                _logger.Trace("Media info is unavailable for {0}", movieFile);

                return;
            }

            var sceneName = movieFile.GetSceneOrFileName();

            var videoCodec     = MediaInfoFormatter.FormatVideoCodec(movieFile.MediaInfo, sceneName);
            var audioCodec     = MediaInfoFormatter.FormatAudioCodec(movieFile.MediaInfo, sceneName);
            var audioChannels  = MediaInfoFormatter.FormatAudioChannels(movieFile.MediaInfo);
            var audioLanguages = movieFile.MediaInfo.AudioLanguages ?? new List <string>();
            var subtitles      = movieFile.MediaInfo.Subtitles ?? new List <string>();

            var mediaInfoAudioLanguages = GetLanguagesToken(audioLanguages);

            if (!mediaInfoAudioLanguages.IsNullOrWhiteSpace())
            {
                mediaInfoAudioLanguages = $"[{mediaInfoAudioLanguages}]";
            }

            var mediaInfoAudioLanguagesAll = mediaInfoAudioLanguages;

            if (mediaInfoAudioLanguages == "[EN]")
            {
                mediaInfoAudioLanguages = string.Empty;
            }

            var mediaInfoSubtitleLanguages = GetLanguagesToken(subtitles);

            if (!mediaInfoSubtitleLanguages.IsNullOrWhiteSpace())
            {
                mediaInfoSubtitleLanguages = $"[{mediaInfoSubtitleLanguages}]";
            }

            var videoBitDepth          = movieFile.MediaInfo.VideoBitDepth > 0 ? movieFile.MediaInfo.VideoBitDepth.ToString() : 8.ToString();
            var audioChannelsFormatted = audioChannels > 0 ?
                                         audioChannels.ToString("F1", CultureInfo.InvariantCulture) :
                                         string.Empty;

            var mediaInfo3D = movieFile.MediaInfo.VideoMultiViewCount > 1 ? "3D" : string.Empty;

            tokenHandlers["{MediaInfo Video}"]         = m => videoCodec;
            tokenHandlers["{MediaInfo VideoCodec}"]    = m => videoCodec;
            tokenHandlers["{MediaInfo VideoBitDepth}"] = m => videoBitDepth;

            tokenHandlers["{MediaInfo Audio}"]             = m => audioCodec;
            tokenHandlers["{MediaInfo AudioCodec}"]        = m => audioCodec;
            tokenHandlers["{MediaInfo AudioChannels}"]     = m => audioChannelsFormatted;
            tokenHandlers["{MediaInfo AudioLanguages}"]    = m => mediaInfoAudioLanguages;
            tokenHandlers["{MediaInfo AudioLanguagesAll}"] = m => mediaInfoAudioLanguagesAll;

            tokenHandlers["{MediaInfo SubtitleLanguages}"]    = m => mediaInfoSubtitleLanguages;
            tokenHandlers["{MediaInfo SubtitleLanguagesAll}"] = m => mediaInfoSubtitleLanguages;

            tokenHandlers["{MediaInfo 3D}"] = m => mediaInfo3D;

            tokenHandlers["{MediaInfo Simple}"] = m => $"{videoCodec} {audioCodec}";
            tokenHandlers["{MediaInfo Full}"]   = m => $"{videoCodec} {audioCodec}{mediaInfoAudioLanguages} {mediaInfoSubtitleLanguages}";

            tokenHandlers[MediaInfoVideoDynamicRangeToken] =
                m => MediaInfoFormatter.FormatVideoDynamicRange(movieFile.MediaInfo);
            tokenHandlers[MediaInfoVideoDynamicRangeTypeToken] =
                m => MediaInfoFormatter.FormatVideoDynamicRangeType(movieFile.MediaInfo);
        }
Example #2
0
        public override MetadataFileResult MovieMetadata(Movie movie, MovieFile movieFile)
        {
            if (!Settings.MovieMetadata)
            {
                return(null);
            }

            _logger.Debug("Generating Movie Metadata for: {0}", Path.Combine(movie.Path, movieFile.RelativePath));

            var watched = GetExistingWatchedStatus(movie, movieFile.RelativePath);

            var xmlResult = string.Empty;

            var sb  = new StringBuilder();
            var xws = new XmlWriterSettings();

            xws.OmitXmlDeclaration = true;
            xws.Indent             = false;

            using (var xw = XmlWriter.Create(sb, xws))
            {
                var doc       = new XDocument();
                var thumbnail = movie.Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot);
                var posters   = movie.Images.Where(i => i.CoverType == MediaCoverTypes.Poster);
                var fanarts   = movie.Images.Where(i => i.CoverType == MediaCoverTypes.Fanart);

                var details = new XElement("movie");

                details.Add(new XElement("title", movie.Title));

                if (movie.Ratings != null && movie.Ratings.Votes > 0)
                {
                    details.Add(new XElement("rating", movie.Ratings.Value));
                }

                details.Add(new XElement("plot", movie.Overview));
                details.Add(new XElement("id", movie.ImdbId));

                if (movie.ImdbId.IsNotNullOrWhiteSpace())
                {
                    var imdbId = new XElement("uniqueid", movie.ImdbId);
                    imdbId.SetAttributeValue("type", "imdb");
                    imdbId.SetAttributeValue("default", true);
                    details.Add(imdbId);
                }

                var uniqueId = new XElement("uniqueid", movie.TmdbId);
                uniqueId.SetAttributeValue("type", "tmdb");
                details.Add(uniqueId);

                details.Add(new XElement("year", movie.Year));

                if (movie.InCinemas.HasValue)
                {
                    details.Add(new XElement("premiered", movie.InCinemas.Value.ToString("yyyy-MM-dd")));
                }

                foreach (var genre in movie.Genres)
                {
                    details.Add(new XElement("genre", genre));
                }

                details.Add(new XElement("studio", movie.Studio));

                if (thumbnail == null)
                {
                    details.Add(new XElement("thumb"));
                }

                else
                {
                    details.Add(new XElement("thumb", thumbnail.Url));
                }

                foreach (var poster in posters)
                {
                    if (poster != null && poster.Url != null)
                    {
                        details.Add(new XElement("thumb", new XAttribute("aspect", "poster"), poster.Url));
                    }
                }

                if (fanarts.Count() > 0)
                {
                    var fanartElement = new XElement("fanart");
                    foreach (var fanart in fanarts)
                    {
                        if (fanart != null && fanart.Url != null)
                        {
                            fanartElement.Add(new XElement("thumb", fanart.Url));
                        }
                    }
                    details.Add(fanartElement);
                }

                details.Add(new XElement("watched", watched));

                if (movieFile.MediaInfo != null)
                {
                    var sceneName = movieFile.GetSceneOrFileName();

                    var fileInfo      = new XElement("fileinfo");
                    var streamDetails = new XElement("streamdetails");

                    var video = new XElement("video");
                    video.Add(new XElement("aspect", (float)movieFile.MediaInfo.Width / (float)movieFile.MediaInfo.Height));
                    video.Add(new XElement("bitrate", movieFile.MediaInfo.VideoBitrate));
                    video.Add(new XElement("codec", MediaInfoFormatter.FormatVideoCodec(movieFile.MediaInfo, sceneName)));
                    video.Add(new XElement("framerate", movieFile.MediaInfo.VideoFps));
                    video.Add(new XElement("height", movieFile.MediaInfo.Height));
                    video.Add(new XElement("scantype", movieFile.MediaInfo.ScanType));
                    video.Add(new XElement("width", movieFile.MediaInfo.Width));

                    if (movieFile.MediaInfo.RunTime != null)
                    {
                        video.Add(new XElement("duration", movieFile.MediaInfo.RunTime.TotalMinutes));
                        video.Add(new XElement("durationinseconds", movieFile.MediaInfo.RunTime.TotalSeconds));
                    }

                    streamDetails.Add(video);

                    var audio = new XElement("audio");
                    audio.Add(new XElement("bitrate", movieFile.MediaInfo.AudioBitrate));
                    audio.Add(new XElement("channels", movieFile.MediaInfo.AudioChannels));
                    audio.Add(new XElement("codec", MediaInfoFormatter.FormatAudioCodec(movieFile.MediaInfo, sceneName)));
                    audio.Add(new XElement("language", movieFile.MediaInfo.AudioLanguages));
                    streamDetails.Add(audio);

                    if (movieFile.MediaInfo.Subtitles != null && movieFile.MediaInfo.Subtitles.Length > 0)
                    {
                        var subtitle = new XElement("subtitle");
                        subtitle.Add(new XElement("language", movieFile.MediaInfo.Subtitles));
                        streamDetails.Add(subtitle);
                    }

                    fileInfo.Add(streamDetails);
                    details.Add(fileInfo);
                }

                doc.Add(details);
                doc.Save(xw);

                xmlResult += doc.ToString();
                xmlResult += Environment.NewLine;
            }

            var metadataFileName = GetMovieMetadataFilename(movieFile.RelativePath);

            if (Settings.UseMovieNfo)
            {
                metadataFileName = "movie.nfo";
            }

            return(new MetadataFileResult(metadataFileName, xmlResult.Trim(Environment.NewLine.ToCharArray())));
        }
Example #3
0
        public override MetadataFileResult MovieMetadata(Movie movie, MovieFile movieFile)
        {
            var xmlResult = string.Empty;

            if (Settings.MovieMetadata)
            {
                _logger.Debug("Generating Movie Metadata for: {0}", Path.Combine(movie.Path, movieFile.RelativePath));

                var movieMetadataLanguage    = (Settings.MovieMetadataLanguage == (int)Language.Original) ? (int)movie.OriginalLanguage : Settings.MovieMetadataLanguage;
                var selectedSettingsLanguage = Language.FindById(movieMetadataLanguage);
                var isoLanguage = IsoLanguages.Get(selectedSettingsLanguage);
                var isoLanguageTwoLetterCode = isoLanguage.TwoLetterCode;
                var countryCode = isoLanguage.CountryCode;

                if (TmdbClient == null)
                {
                    TmdbClient = new TMDbClient(Settings.ApiKey)
                    {
                        DefaultCountry     = countryCode,
                        DefaultLanguage    = isoLanguageTwoLetterCode,
                        ThrowApiExceptions = true
                    };
                }

                var extraMethods =
                    TMDbLibMovies.MovieMethods.Credits |
                    TMDbLibMovies.MovieMethods.Releases |
                    TMDbLibMovies.MovieMethods.Videos;

                TMDbLibMovies.Movie tmdbMovie = null;
                try
                {
                    tmdbMovie = TmdbClient.GetMovieAsync(movie.TmdbId, extraMethods).Result;
                }
                catch (Exception exception)
                {
                    _logger.Error(exception, "Fail to obtain Tmdb Movie Metadata for: {0}", Path.Combine(movie.Path, movieFile.RelativePath));
                }

                Collection tmdbMovieCollection = null;
                if (tmdbMovie.BelongsToCollection != null)
                {
                    try
                    {
                        tmdbMovieCollection = TmdbClient.GetCollectionAsync(tmdbMovie.BelongsToCollection.Id).Result;
                    }
                    catch (Exception exception)
                    {
                        _logger.Error(exception, "Fail to obtain Tmdb Movie Collection Metadata for: {0}", Path.Combine(movie.Path, movieFile.RelativePath));
                    }
                }

                var sb  = new StringBuilder();
                var xws = new XmlWriterSettings
                {
                    OmitXmlDeclaration = false,
                    Encoding           = Encoding.UTF8,
                    Indent             = false
                };

                if (tmdbMovie != null)
                {
                    using (var xw = XmlWriter.Create(sb, xws))
                    {
                        var doc = new XDocument();

                        var details = new XElement("movie");

                        details.Add(new XElement("title", tmdbMovie.Title));

                        details.Add(new XElement("originaltitle", tmdbMovie.OriginalTitle));

                        details.Add(new XElement("sorttitle", tmdbMovie.Title.ToLowerInvariant()));

                        if (tmdbMovie.VoteAverage > 0)
                        {
                            var setRating         = new XElement("ratings");
                            var setRatethemoviedb = new XElement("rating", new XAttribute("name", "themoviedb"), new XAttribute("max", "10"), new XAttribute("default", "true"));
                            setRatethemoviedb.Add(new XElement("value", tmdbMovie.VoteAverage));
                            setRatethemoviedb.Add(new XElement("votes", tmdbMovie.VoteCount));
                            setRating.Add(setRatethemoviedb);
                            details.Add(setRating);
                        }

                        details.Add(new XElement("rating", tmdbMovie.VoteAverage));

                        details.Add(new XElement("top250"));

                        var outlineEndPosition = tmdbMovie.Overview.IndexOf(". ");
                        details.Add(new XElement("outline", tmdbMovie.Overview.Substring(0, outlineEndPosition > 0 ? outlineEndPosition + 1 : tmdbMovie.Overview.Length)));

                        details.Add(new XElement("plot", tmdbMovie.Overview));

                        details.Add(new XElement("tagline", tmdbMovie.Tagline));

                        details.Add(new XElement("runtime", tmdbMovie.Runtime));

                        if (tmdbMovie.PosterPath != null)
                        {
                            details.Add(new XElement("thumb", new XAttribute("aspect", CoverType.poster), new XAttribute("preview", BaseImageUrl + "/w185" + tmdbMovie.PosterPath), BaseImageUrl + "/original" + tmdbMovie.PosterPath));
                        }

                        if (Settings.FanartApiKey.IsNotNullOrWhiteSpace())
                        {
                            string content = null;

                            try
                            {
                                var fanartRequest  = new HttpRequest($"http://webservice.fanart.tv/v3/movies/{movie.TmdbId}?api_key={Settings.FanartApiKey}", HttpAccept.Json);
                                var fanartResponse = _client.Execute(fanartRequest);

                                content = fanartResponse.Content;
                            }
                            catch (Exception e)
                            {
                                _logger.Error(e, "Can't obtain data from Fanart for Movie: {0}", Path.Combine(movie.Path, movieFile.RelativePath));
                            }

                            if (content.IsNotNullOrWhiteSpace())
                            {
                                var originalLanguageTwoLetterCode = tmdbMovie.OriginalLanguage;
                                var fanartMovie = Json.Deserialize <FanartMovie>(content);

                                if (fanartMovie != null)
                                {
                                    var moviebanner = GetBestOptionForFanartMovieArt(fanartMovie.moviebanner, isoLanguageTwoLetterCode, originalLanguageTwoLetterCode);
                                    if (moviebanner != null)
                                    {
                                        details.Add(new XElement("thumb", new XAttribute("aspect", CoverType.banner), new XAttribute("preview", moviebanner.url.Replace("/fanart/", "/preview/")), moviebanner.url));
                                    }

                                    var hdmovieclearart = GetBestOptionForFanartMovieArt(fanartMovie.hdmovieclearart, isoLanguageTwoLetterCode, originalLanguageTwoLetterCode);
                                    if (hdmovieclearart != null)
                                    {
                                        details.Add(new XElement("thumb", new XAttribute("aspect", CoverType.clearart), new XAttribute("preview", hdmovieclearart.url.Replace("/fanart/", "/preview/")), hdmovieclearart.url));
                                    }

                                    var hdmovielogo = GetBestOptionForFanartMovieArt(fanartMovie.hdmovielogo, isoLanguageTwoLetterCode, originalLanguageTwoLetterCode);
                                    if (hdmovielogo != null)
                                    {
                                        details.Add(new XElement("thumb", new XAttribute("aspect", CoverType.clearlogo), new XAttribute("preview", hdmovielogo.url.Replace("/fanart/", "/preview/")), hdmovielogo.url));
                                    }

                                    if (fanartMovie.moviedisc != null)
                                    {
                                        var moviedisc = GetBestOptionForFanartMovieArt(fanartMovie.moviedisc.Cast <FanartMovieArt>().ToList(), isoLanguageTwoLetterCode, originalLanguageTwoLetterCode);
                                        if (moviedisc != null)
                                        {
                                            details.Add(new XElement("thumb", new XAttribute("aspect", CoverType.discart), new XAttribute("preview", moviedisc.url.Replace("/fanart/", "/preview/")), moviedisc.url));
                                        }
                                    }

                                    var moviethumb = GetBestOptionForFanartMovieArt(fanartMovie.moviethumb, isoLanguageTwoLetterCode, originalLanguageTwoLetterCode);
                                    if (moviethumb != null)
                                    {
                                        details.Add(new XElement("thumb", new XAttribute("aspect", CoverType.landscape), new XAttribute("preview", moviethumb.url.Replace("/fanart/", "/preview/")), moviethumb.url));
                                    }
                                }
                            }
                        }

                        if (tmdbMovie.BackdropPath != null)
                        {
                            details.Add(new XElement("fanart", new XElement("thumb", new XAttribute("preview", BaseImageUrl + "/w300" + tmdbMovie.BackdropPath), BaseImageUrl + "/original" + tmdbMovie.BackdropPath)));
                        }

                        if (tmdbMovie.Releases?.Countries != null)
                        {
                            var releases   = tmdbMovie.Releases.Countries.Where(i => !string.IsNullOrWhiteSpace(i.Certification)).ToList();
                            var ourRelease = releases.FirstOrDefault(c => string.Equals(c.Iso_3166_1, isoLanguageTwoLetterCode, StringComparison.OrdinalIgnoreCase));
                            var usRelease  = releases.FirstOrDefault(c => string.Equals(c.Iso_3166_1, "US", StringComparison.OrdinalIgnoreCase));

                            if (ourRelease != null)
                            {
                                var ratingPrefix = string.Equals(isoLanguageTwoLetterCode, "US", StringComparison.OrdinalIgnoreCase) ? string.Empty : isoLanguageTwoLetterCode.ToUpperInvariant() + "-";
                                var newRating    = ratingPrefix + ourRelease.Certification.Replace("DE-", "FSK-");

                                details.Add(new XElement("mpaa", newRating));
                            }
                            else if (usRelease != null)
                            {
                                details.Add(new XElement("mpaa", usRelease.Certification));
                            }
                        }

                        var uniqueId = new XElement("uniqueid", tmdbMovie.Id);
                        uniqueId.SetAttributeValue("type", "tmdb");
                        uniqueId.SetAttributeValue("default", true);
                        details.Add(uniqueId);
                        details.Add(new XElement("tmdbid", tmdbMovie.Id));

                        if (tmdbMovie.ImdbId.IsNotNullOrWhiteSpace())
                        {
                            var imdbId = new XElement("uniqueid", tmdbMovie.ImdbId);
                            imdbId.SetAttributeValue("type", "imdb");
                            details.Add(imdbId);
                            details.Add(new XElement("imdbid", tmdbMovie.ImdbId));
                        }

                        foreach (var genre in tmdbMovie.Genres)
                        {
                            details.Add(new XElement("genre", genre.Name));
                        }

                        foreach (var country in tmdbMovie.ProductionCountries)
                        {
                            details.Add(new XElement("country", country.Name));
                        }

                        if (tmdbMovieCollection != null)
                        {
                            details.Add(new XElement("collectionnumber", tmdbMovieCollection.Id));

                            var setElement = new XElement("set");
                            setElement.SetAttributeValue("tmdbcolid", tmdbMovieCollection.Id);

                            setElement.Add(new XElement("name", tmdbMovieCollection.Name));
                            setElement.Add(new XElement("overview", tmdbMovieCollection.Overview));

                            details.Add(setElement);
                        }

                        foreach (var writer in tmdbMovie.Credits.Crew.Where(crew => (crew.Job == "Screenplay" || crew.Job == "Story" || crew.Job == "Novel" || crew.Job == "Writer") && crew.Name.IsNotNullOrWhiteSpace()))
                        {
                            details.Add(new XElement("credits", writer.Name));
                        }

                        foreach (var director in tmdbMovie.Credits.Crew.Where(crew => crew.Job == "Director" && crew.Name.IsNotNullOrWhiteSpace()))
                        {
                            details.Add(new XElement("director", director.Name));
                        }

                        if (tmdbMovie.ReleaseDate.HasValue)
                        {
                            details.Add(new XElement("releasedate", tmdbMovie.ReleaseDate.Value.ToString("yyyy-MM-dd")));
                            details.Add(new XElement("premiered", tmdbMovie.ReleaseDate.Value.ToString("yyyy-MM-dd")));
                            details.Add(new XElement("year", tmdbMovie.ReleaseDate.Value.Year));
                        }

                        details.Add(new XElement("status", tmdbMovie.Status));

                        foreach (var company in tmdbMovie.ProductionCompanies)
                        {
                            details.Add(new XElement("studio", company.Name));
                        }

                        details.Add(new XElement("trailer", GetYoutubeTrailer(tmdbMovie)));

                        if (movieFile.MediaInfo != null)
                        {
                            var sceneName = movieFile.GetSceneOrFileName();

                            var fileInfo      = new XElement("fileinfo");
                            var streamDetails = new XElement("streamdetails");

                            var video = new XElement("video");
                            video.Add(new XElement("aspect", movieFile.MediaInfo.Width / movieFile.MediaInfo.Height));
                            video.Add(new XElement("bitrate", movieFile.MediaInfo.VideoBitrate));
                            video.Add(new XElement("codec", MediaInfoFormatter.FormatVideoCodec(movieFile.MediaInfo, sceneName)));
                            video.Add(new XElement("framerate", movieFile.MediaInfo.VideoFps));
                            video.Add(new XElement("height", movieFile.MediaInfo.Height));
                            video.Add(new XElement("scantype", movieFile.MediaInfo.ScanType));
                            video.Add(new XElement("width", movieFile.MediaInfo.Width));

                            if (movieFile.MediaInfo.RunTime != default)
                            {
                                video.Add(new XElement("duration", movieFile.MediaInfo.RunTime.TotalMinutes));
                                video.Add(new XElement("durationinseconds", Math.Round(movieFile.MediaInfo.RunTime.TotalSeconds)));
                            }

                            streamDetails.Add(video);

                            var audio             = new XElement("audio");
                            var audioChannelCount = movieFile.MediaInfo.AudioChannels;
                            audio.Add(new XElement("bitrate", movieFile.MediaInfo.AudioBitrate));
                            audio.Add(new XElement("channels", audioChannelCount));
                            audio.Add(new XElement("codec", MediaInfoFormatter.FormatAudioCodec(movieFile.MediaInfo, sceneName)));
                            audio.Add(new XElement("language", movieFile.MediaInfo.AudioLanguages));
                            streamDetails.Add(audio);

                            if (movieFile.MediaInfo.Subtitles != null && movieFile.MediaInfo.Subtitles.Count > 0)
                            {
                                var subtitle = new XElement("subtitle");
                                subtitle.Add(new XElement("language", movieFile.MediaInfo.Subtitles));
                                streamDetails.Add(subtitle);
                            }

                            fileInfo.Add(streamDetails);
                            details.Add(fileInfo);

                            foreach (var cast in tmdbMovie.Credits.Cast)
                            {
                                if (cast.Name.IsNotNullOrWhiteSpace() && cast.Character.IsNotNullOrWhiteSpace())
                                {
                                    var actorElement = new XElement("actor");

                                    actorElement.Add(new XElement("name", cast.Name));
                                    actorElement.Add(new XElement("role", cast.Character));
                                    actorElement.Add(new XElement("order", cast.Order));

                                    if (cast.ProfilePath.IsNotNullOrWhiteSpace())
                                    {
                                        actorElement.Add(new XElement("thumb", BaseImageUrl + "/original" + cast.ProfilePath));
                                    }

                                    details.Add(actorElement);
                                }
                            }

                            details.Add(new XElement("dateadded", movieFile.DateAdded.ToString("s")));
                        }

                        doc.Add(details);
                        doc.Save(xw);

                        xmlResult += doc.ToString();
                        xmlResult += Environment.NewLine;
                    }
                }
            }

            if (Settings.MovieMetadataURL)
            {
                xmlResult += "https://www.themoviedb.org/movie/" + movie.TmdbId;
                xmlResult += Environment.NewLine;

                xmlResult += "https://www.imdb.com/title/" + movie.ImdbId;
                xmlResult += Environment.NewLine;
            }

            var metadataFileName = GetMovieMetadataFilename(movieFile.RelativePath);

            return(string.IsNullOrEmpty(xmlResult) ? null : new MetadataFileResult(metadataFileName, xmlResult.Trim(Environment.NewLine.ToCharArray())));
        }
Example #4
0
        public override MetadataFileResult MovieMetadata(Movie movie, MovieFile movieFile)
        {
            var xmlResult = string.Empty;

            if (Settings.MovieMetadata)
            {
                _logger.Debug("Generating Movie Metadata for: {0}", Path.Combine(movie.Path, movieFile.RelativePath));

                var movieMetadataLanguage = (Settings.MovieMetadataLanguage == (int)Language.Original) ?
                                            (int)movie.OriginalLanguage :
                                            Settings.MovieMetadataLanguage;

                var movieTranslations        = _movieTranslationsService.GetAllTranslationsForMovie(movie.Id);
                var selectedSettingsLanguage = Language.FindById(movieMetadataLanguage);
                var movieTranslation         = movieTranslations.FirstOrDefault(mt => mt.Language == selectedSettingsLanguage);

                var credits = _creditService.GetAllCreditsForMovie(movie.Id);

                var watched = GetExistingWatchedStatus(movie, movieFile.RelativePath);

                var sb  = new StringBuilder();
                var xws = new XmlWriterSettings();
                xws.OmitXmlDeclaration = true;
                xws.Indent             = false;

                using (var xw = XmlWriter.Create(sb, xws))
                {
                    var doc       = new XDocument();
                    var thumbnail = movie.Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot);
                    var posters   = movie.Images.Where(i => i.CoverType == MediaCoverTypes.Poster);
                    var fanarts   = movie.Images.Where(i => i.CoverType == MediaCoverTypes.Fanart);

                    var details = new XElement("movie");

                    details.Add(new XElement("title", movieTranslation?.Title ?? movie.Title));

                    details.Add(new XElement("originaltitle", movie.OriginalTitle));

                    details.Add(new XElement("sorttitle", movie.SortTitle));

                    if (movie.Ratings != null && movie.Ratings.Votes > 0)
                    {
                        var setRating         = new XElement("ratings");
                        var setRatethemoviedb = new XElement("rating", new XAttribute("name", "themoviedb"), new XAttribute("max", "10"), new XAttribute("default", "true"));
                        setRatethemoviedb.Add(new XElement("value", movie.Ratings.Value));
                        setRatethemoviedb.Add(new XElement("votes", movie.Ratings.Votes));
                        setRating.Add(setRatethemoviedb);
                        details.Add(setRating);
                    }

                    if (movie.Ratings != null && movie.Ratings.Votes > 0)
                    {
                        details.Add(new XElement("rating", movie.Ratings.Value));
                    }

                    details.Add(new XElement("userrating"));

                    details.Add(new XElement("top250"));

                    details.Add(new XElement("outline"));

                    details.Add(new XElement("plot", movieTranslation?.Overview ?? movie.Overview));

                    details.Add(new XElement("tagline"));

                    details.Add(new XElement("runtime", movie.Runtime));

                    if (thumbnail != null)
                    {
                        details.Add(new XElement("thumb", thumbnail.Url));
                    }

                    foreach (var poster in posters)
                    {
                        if (poster != null && poster.Url != null)
                        {
                            details.Add(new XElement("thumb", new XAttribute("aspect", "poster"), new XAttribute("preview", poster.Url), poster.Url));
                        }
                    }

                    if (fanarts.Any())
                    {
                        var fanartElement = new XElement("fanart");
                        foreach (var fanart in fanarts)
                        {
                            if (fanart != null && fanart.Url != null)
                            {
                                fanartElement.Add(new XElement("thumb", new XAttribute("preview", fanart.Url), fanart.Url));
                            }
                        }

                        details.Add(fanartElement);
                    }

                    if (movie.Certification.IsNotNullOrWhiteSpace())
                    {
                        details.Add(new XElement("mpaa", movie.Certification));
                    }

                    details.Add(new XElement("playcount"));

                    details.Add(new XElement("lastplayed"));

                    details.Add(new XElement("id", movie.TmdbId));

                    var uniqueId = new XElement("uniqueid", movie.TmdbId);
                    uniqueId.SetAttributeValue("type", "tmdb");
                    uniqueId.SetAttributeValue("default", true);
                    details.Add(uniqueId);

                    if (movie.ImdbId.IsNotNullOrWhiteSpace())
                    {
                        var imdbId = new XElement("uniqueid", movie.ImdbId);
                        imdbId.SetAttributeValue("type", "imdb");
                        details.Add(imdbId);
                    }

                    foreach (var genre in movie.Genres)
                    {
                        details.Add(new XElement("genre", genre));
                    }

                    details.Add(new XElement("country"));

                    if (movie.Collection?.Name != null)
                    {
                        var setElement = new XElement("set");

                        setElement.Add(new XElement("name", movie.Collection.Name));
                        setElement.Add(new XElement("overview"));

                        details.Add(setElement);
                    }

                    foreach (var tag in movie.Tags)
                    {
                        details.Add(new XElement("tag", tag));
                    }

                    foreach (var credit in credits)
                    {
                        if (credit.Name != null && credit.Job == "Screenplay")
                        {
                            details.Add(new XElement("credits", credit.Name));
                        }
                    }

                    foreach (var credit in credits)
                    {
                        if (credit.Name != null && credit.Job == "Director")
                        {
                            details.Add(new XElement("director", credit.Name));
                        }
                    }

                    if (movie.InCinemas.HasValue)
                    {
                        details.Add(new XElement("premiered", movie.InCinemas.Value.ToString("yyyy-MM-dd")));
                    }

                    details.Add(new XElement("year", movie.Year));

                    details.Add(new XElement("studio", movie.Studio));

                    details.Add(new XElement("trailer", "https://www.youtube.com/watch?v=" + movie.YouTubeTrailerId));

                    if (movieFile.MediaInfo != null)
                    {
                        var sceneName = movieFile.GetSceneOrFileName();

                        var fileInfo      = new XElement("fileinfo");
                        var streamDetails = new XElement("streamdetails");

                        var video = new XElement("video");
                        video.Add(new XElement("aspect", (float)movieFile.MediaInfo.Width / (float)movieFile.MediaInfo.Height));
                        video.Add(new XElement("bitrate", movieFile.MediaInfo.VideoBitrate));
                        video.Add(new XElement("codec", MediaInfoFormatter.FormatVideoCodec(movieFile.MediaInfo, sceneName)));
                        video.Add(new XElement("framerate", movieFile.MediaInfo.VideoFps));
                        video.Add(new XElement("height", movieFile.MediaInfo.Height));
                        video.Add(new XElement("scantype", movieFile.MediaInfo.ScanType));
                        video.Add(new XElement("width", movieFile.MediaInfo.Width));

                        if (movieFile.MediaInfo.RunTime != null)
                        {
                            video.Add(new XElement("duration", movieFile.MediaInfo.RunTime.TotalMinutes));
                            video.Add(new XElement("durationinseconds", movieFile.MediaInfo.RunTime.TotalSeconds));
                        }

                        streamDetails.Add(video);

                        var audio             = new XElement("audio");
                        var audioChannelCount = movieFile.MediaInfo.AudioChannelsStream > 0 ? movieFile.MediaInfo.AudioChannelsStream : movieFile.MediaInfo.AudioChannelsContainer;
                        audio.Add(new XElement("bitrate", movieFile.MediaInfo.AudioBitrate));
                        audio.Add(new XElement("channels", audioChannelCount));
                        audio.Add(new XElement("codec", MediaInfoFormatter.FormatAudioCodec(movieFile.MediaInfo, sceneName)));
                        audio.Add(new XElement("language", movieFile.MediaInfo.AudioLanguages));
                        streamDetails.Add(audio);

                        if (movieFile.MediaInfo.Subtitles != null && movieFile.MediaInfo.Subtitles.Length > 0)
                        {
                            var subtitle = new XElement("subtitle");
                            subtitle.Add(new XElement("language", movieFile.MediaInfo.Subtitles));
                            streamDetails.Add(subtitle);
                        }

                        fileInfo.Add(streamDetails);
                        details.Add(fileInfo);

                        foreach (var credit in credits)
                        {
                            if (credit.Name != null && credit.Character != null)
                            {
                                var actorElement = new XElement("actor");

                                actorElement.Add(new XElement("name", credit.Name));
                                actorElement.Add(new XElement("role", credit.Character));
                                actorElement.Add(new XElement("order", credit.Order));

                                var headshot = credit.Images.FirstOrDefault(m => m.CoverType == MediaCoverTypes.Headshot);

                                if (headshot != null && headshot.Url != null)
                                {
                                    actorElement.Add(new XElement("thumb", headshot.Url));
                                }

                                details.Add(actorElement);
                            }
                        }
                    }

                    doc.Add(details);
                    doc.Save(xw);

                    xmlResult += doc.ToString();
                    xmlResult += Environment.NewLine;
                }
            }

            if (Settings.MovieMetadataURL)
            {
                xmlResult += "https://www.themoviedb.org/movie/" + movie.TmdbId;
                xmlResult += Environment.NewLine;

                xmlResult += "https://www.imdb.com/title/" + movie.ImdbId;
                xmlResult += Environment.NewLine;
            }

            var metadataFileName = GetMovieMetadataFilename(movieFile.RelativePath);

            return(string.IsNullOrEmpty(xmlResult) ? null : new MetadataFileResult(metadataFileName, xmlResult.Trim(Environment.NewLine.ToCharArray())));
        }
Example #5
0
        private void AddMediaInfoTokens(Dictionary <string, Func <TokenMatch, string> > tokenHandlers, MovieFile movieFile)
        {
            if (movieFile.MediaInfo == null)
            {
                return;
            }

            var sceneName = movieFile.GetSceneOrFileName();

            var videoCodec    = MediaInfoFormatter.FormatVideoCodec(movieFile.MediaInfo, sceneName);
            var audioCodec    = MediaInfoFormatter.FormatAudioCodec(movieFile.MediaInfo, sceneName);
            var audioChannels = MediaInfoFormatter.FormatAudioChannels(movieFile.MediaInfo);

            // Workaround until https://github.com/MediaArea/MediaInfo/issues/299 is fixed and release
            if (audioCodec.EqualsIgnoreCase("DTS-X"))
            {
                audioChannels = audioChannels - 1 + 0.1m;
            }

            var mediaInfoAudioLanguages = GetLanguagesToken(movieFile.MediaInfo.AudioLanguages);

            if (!mediaInfoAudioLanguages.IsNullOrWhiteSpace())
            {
                mediaInfoAudioLanguages = $"[{mediaInfoAudioLanguages}]";
            }
            var mediaInfoAudioLanguagesAll = mediaInfoAudioLanguages;

            if (mediaInfoAudioLanguages == "[EN]")
            {
                mediaInfoAudioLanguages = string.Empty;
            }

            var mediaInfoSubtitleLanguages = GetLanguagesToken(movieFile.MediaInfo.Subtitles);

            if (!mediaInfoSubtitleLanguages.IsNullOrWhiteSpace())
            {
                mediaInfoSubtitleLanguages = $"[{mediaInfoSubtitleLanguages}]";
            }

            var videoBitDepth          = movieFile.MediaInfo.VideoBitDepth > 0 ? movieFile.MediaInfo.VideoBitDepth.ToString() : string.Empty;
            var audioChannelsFormatted = audioChannels > 0 ?
                                         audioChannels.ToString("F1", CultureInfo.InvariantCulture) :
                                         string.Empty;

            var mediaInfo3D = movieFile.MediaInfo.VideoMultiViewCount > 1 ? "3D" : string.Empty;

            var videoColourPrimaries         = movieFile.MediaInfo.VideoColourPrimaries ?? string.Empty;
            var videoTransferCharacteristics = movieFile.MediaInfo.VideoTransferCharacteristics ?? string.Empty;
            var mediaInfoHDR = string.Empty;

            if (movieFile.MediaInfo.VideoBitDepth >= 10 && !videoColourPrimaries.IsNullOrWhiteSpace() && !videoTransferCharacteristics.IsNullOrWhiteSpace())
            {
                string[] validTransferFunctions = new string[] { "PQ", "HLG" };

                if (videoColourPrimaries.EqualsIgnoreCase("BT.2020") && validTransferFunctions.Any(videoTransferCharacteristics.Contains))
                {
                    mediaInfoHDR = "HDR";
                }
            }

            tokenHandlers["{MediaInfo Video}"]         = m => videoCodec;
            tokenHandlers["{MediaInfo VideoCodec}"]    = m => videoCodec;
            tokenHandlers["{MediaInfo VideoBitDepth}"] = m => videoBitDepth;

            tokenHandlers["{MediaInfo Audio}"]             = m => audioCodec;
            tokenHandlers["{MediaInfo AudioCodec}"]        = m => audioCodec;
            tokenHandlers["{MediaInfo AudioChannels}"]     = m => audioChannelsFormatted;
            tokenHandlers["{MediaInfo AudioLanguages}"]    = m => mediaInfoAudioLanguages;
            tokenHandlers["{MediaInfo AudioLanguagesAll}"] = m => mediaInfoAudioLanguagesAll;

            tokenHandlers["{MediaInfo SubtitleLanguages}"] = m => mediaInfoSubtitleLanguages;

            tokenHandlers["{MediaInfo 3D}"]  = m => mediaInfo3D;
            tokenHandlers["{MediaInfo HDR}"] = m => mediaInfoHDR;

            tokenHandlers["{MediaInfo Simple}"] = m => $"{videoCodec} {audioCodec}";
            tokenHandlers["{MediaInfo Full}"]   = m => $"{videoCodec} {audioCodec}{mediaInfoAudioLanguages} {mediaInfoSubtitleLanguages}";
        }