private async Task SaveNewId(string movieId, string path)
        {
            MovieMetadata metadata = await _metadataService.Get(path);

            metadata.Id = movieId;
            await _metadataService.Save(path, metadata);
        }
        public async Task SaveAsync(int movieId, MovieMetadata metadata)
        {
            var movie = await this.MovieRepository.GetById(movieId, this.MovieRepository.AllColumnNames);

            //reprocess this movie so the library is updated with its info
            await this.LibGenMovieRepository.Process(movie.GetFolderPath(), metadata);
        }
Beispiel #3
0
    internal static MovieViewModel ProjectToViewModel(
        Movie movie,
        string localPath,
        List <string> languageCodes,
        Option <JellyfinMediaSource> maybeJellyfin,
        Option <EmbyMediaSource> maybeEmby)
    {
        MovieMetadata metadata = Optional(movie.MovieMetadata).Flatten().Head();

        return(new MovieViewModel(
                   metadata.Title,
                   metadata.Year?.ToString(),
                   metadata.Plot,
                   metadata.Genres.Map(g => g.Name).ToList(),
                   metadata.Tags.Map(t => t.Name).ToList(),
                   metadata.Studios.Map(s => s.Name).ToList(),
                   (metadata.ContentRating ?? string.Empty).Split("/").Map(s => s.Trim())
                   .Where(x => !string.IsNullOrWhiteSpace(x)).ToList(),
                   LanguagesForMovie(languageCodes),
                   metadata.Actors.OrderBy(a => a.Order).ThenBy(a => a.Id)
                   .Map(a => MediaCards.Mapper.ProjectToViewModel(a, maybeJellyfin, maybeEmby))
                   .ToList(),
                   metadata.Directors.Map(d => d.Name).ToList(),
                   metadata.Writers.Map(w => w.Name).ToList(),
                   movie.GetHeadVersion().MediaFiles.Head().Path,
                   localPath,
                   movie.State)
        {
            Poster = Artwork(metadata, ArtworkKind.Poster, maybeJellyfin, maybeEmby),
            FanArt = Artwork(metadata, ArtworkKind.FanArt, maybeJellyfin, maybeEmby)
        });
    }
Beispiel #4
0
        private void RefreshFromMetadata(MovieMetadata metadata)
        {
            Certification   = metadata.Certification;
            FileInformation = metadata.FileInformation;
            Id               = metadata.Id;
            OriginalTitle    = metadata.OriginalTitle;
            Outline          = metadata.Outline;
            PlayCount        = metadata.PlayCount;
            Plot             = metadata.Plot;
            PremieredDate    = metadata.Premiered;
            Rating           = metadata.Rating;
            RuntimeInMinutes = metadata.RuntimeInMinutes;
            Country          = metadata.Country;
            SetName.Value    = metadata.SetName;
            SetName.Save();
            Studio      = metadata.Studio;
            Tagline     = metadata.Tagline;
            Title.Value = metadata.Title;
            Title.Save();
            Year = metadata.Year;
            Poster.RefreshImage(metadata.ImagePosterPath);
            Fanart.RefreshImage(metadata.ImageFanartPath);

            Credits.ReplaceWith(metadata.Credits);
            Directors.ReplaceWith(metadata.Directors);
            Genres.ReplaceWith(metadata.Genres);
            ActorManager.Initialize(TransformActors(metadata.Actors));
        }
Beispiel #5
0
        private void UpdateMovie(Movie movie, IndexWriter writer)
        {
            Option <MovieMetadata> maybeMetadata = movie.MovieMetadata.HeadOrNone();

            if (maybeMetadata.IsSome)
            {
                MovieMetadata metadata = maybeMetadata.ValueUnsafe();

                try
                {
                    var doc = new Document
                    {
                        new StringField(IdField, movie.Id.ToString(), Field.Store.YES),
                        new StringField(TypeField, MovieType, Field.Store.NO),
                        new TextField(TitleField, metadata.Title, Field.Store.NO),
                        new StringField(SortTitleField, metadata.SortTitle.ToLowerInvariant(), Field.Store.NO),
                        new TextField(LibraryNameField, movie.LibraryPath.Library.Name, Field.Store.NO),
                        new StringField(TitleAndYearField, GetTitleAndYear(metadata), Field.Store.NO),
                        new StringField(JumpLetterField, GetJumpLetter(metadata), Field.Store.YES)
                    };

                    if (metadata.ReleaseDate.HasValue)
                    {
                        doc.Add(
                            new StringField(
                                ReleaseDateField,
                                metadata.ReleaseDate.Value.ToString("yyyyMMdd"),
                                Field.Store.NO));
                    }

                    if (!string.IsNullOrWhiteSpace(metadata.Plot))
                    {
                        doc.Add(new TextField(PlotField, metadata.Plot ?? string.Empty, Field.Store.NO));
                    }

                    foreach (Genre genre in metadata.Genres)
                    {
                        doc.Add(new TextField(GenreField, genre.Name, Field.Store.NO));
                    }

                    foreach (Tag tag in metadata.Tags)
                    {
                        doc.Add(new TextField(TagField, tag.Name, Field.Store.NO));
                    }

                    foreach (Studio studio in metadata.Studios)
                    {
                        doc.Add(new TextField(StudioField, studio.Name, Field.Store.NO));
                    }

                    writer.UpdateDocument(new Term(IdField, movie.Id.ToString()), doc);
                }
                catch (Exception ex)
                {
                    metadata.Movie = null;
                    _logger.LogWarning(ex, "Error indexing movie with metadata {@Metadata}", metadata);
                }
            }
        }
        /// <summary>
        /// Fill in all the metadata on serach result.
        /// </summary>
        private SearchResult CreateSearchResult(DataRow movieData)
        {
            // Grab all the available metadata from the data source.
            MovieMetadata metadata = ExtractMetadata(movieData);

            // Create the search result object
            SearchResult item = new SearchResult(metadata.Id);

            item.Type = Z.Resources.Movies_Search_Type;

            //
            // Fill in all the string metadata.
            //

            item.Description = metadata.Title;

            string cast = String.Empty;

            foreach (string actor in metadata.Actors)
            {
                Z.DataSetHelpers.AppendCommaSeparatedValue(ref cast, actor);
            }

            item.Metadata1 = String.Format(Z.Resources.Movies_Search_Metadata1,
                                           metadata.Genre,
                                           cast,
                                           metadata.Length,
                                           metadata.CountryShortName,
                                           metadata.ReleaseDate.Year);

            item.Metadata2 = String.Format(Z.Resources.Movies_Search_Metadata2,
                                           metadata.Genre,
                                           cast,
                                           metadata.Length,
                                           metadata.CountryShortName,
                                           metadata.ReleaseDate.Year);

            //
            // Load the image.
            //

            string imageName = (string)movieData["Movie_Image_Gallery_Small"];

            item.Image = LoadImage(imageName);


            // Hook up an invoked handler
            item.Invoked += delegate(object sender, EventArgs args)
            {
                SearchResult searchResult = (SearchResult)sender;

                // Navigate to a details page for this item.
                DetailsPage page = CreateDetailsPage(searchResult.Id);
                Application.Current.GoToDetails(page);
            };

            return(item);
        }
Beispiel #7
0
        protected override async Task SaveInternal()
        {
            Title.Save();
            SetName.Save();
            await ActorManager.Save();

            MovieMetadata metadata = CreateMetadata();
            await _metadataService.Save(Path, metadata);
        }
Beispiel #8
0
        public MovieService()
        {
            var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"Data\metadata.csv");

            this.Database = File.ReadAllLines(path)
                            .Skip(1)
                            .Select(v => MovieMetadata.FromCsv(v))
                            .ToList();
        }
Beispiel #9
0
        public MovieMetadata GetFallbackMetadata(Movie movie)
        {
            string path     = movie.MediaVersions.Head().MediaFiles.Head().Path;
            string fileName = Path.GetFileName(path);
            var    metadata = new MovieMetadata {
                MetadataKind = MetadataKind.Fallback, Title = fileName ?? path
            };

            return(fileName != null?GetMovieMetadata(fileName, metadata) : metadata);
        }
Beispiel #10
0
    int GetThumbnailSeconds(MovieMetadata mm)
    {
        var frameAtSecond = 2;

        if (mm.VideoDuration < 2)
        {
            frameAtSecond = 0;
        }

        return(frameAtSecond);
    }
Beispiel #11
0
        /// <summary>
        /// Process the movie at the given path.
        /// </summary>
        /// <param name="moviePath"></param>
        /// <returns></returns>
        public async Task Process(string moviePath, MovieMetadata metadata = null)
        {
            moviePath = Utility.NormalizePath(moviePath, false);
            var sources = await this.SourceRepository.GetAll();

            //remove the movie folder name
            var parentPath = Utility.NormalizePath(Path.GetDirectoryName(Path.GetDirectoryName(moviePath)).ToLowerInvariant(), false);
            var source     = sources.Where(x => Utility.NormalizePath(x.FolderPath.ToLowerInvariant(), false) == parentPath).FirstOrDefault();
            var movie      = this.LibGenFactory.BuildMovie(moviePath, source.Id);
            await movie.ProcessExistingMovie(metadata);
        }
        /// <summary>
        /// Create a details page for a movie.
        /// NOTE: This is public to enable debug markup access.
        /// </summary>
        public DetailsPage CreateDetailsPage(int movieId)
        {
            DetailsPage page = new DetailsPage();

            //
            // Get the full metadata from this row.
            //

            DataRow       movieData = GetMovieData(movieId);
            MovieMetadata metadata  = ExtractMetadata(movieData, movieId);


            //
            // Fill in the page's easy properties.
            //

            page.Title      = metadata.Title;
            page.Summary    = metadata.Summary;
            page.Background = LoadImage(metadata.ImagePath);


            //
            // Metadata
            //
            // Now that we have all the little pieces, we can put together our
            // final metadata string.
            //

            string cast = String.Empty;

            foreach (string actor in metadata.Actors)
            {
                Z.DataSetHelpers.AppendCommaSeparatedValue(ref cast, actor);
            }

            page.Metadata = String.Format(Z.Resources.Movies_Details_Metadata,
                                          metadata.Genre,
                                          cast,
                                          metadata.Length,
                                          metadata.CountryShortName,
                                          metadata.ReleaseDate.Year);


            //
            // Actions
            //

            CreateDetailsCommands(page, movieData, movieId);

            return(page);
        }
Beispiel #13
0
    void PopulateVideoMetadata(string localSourceFile, MovieMetadata mm)
    {
        var tags = _exifTool.GetTagsAsync(localSourceFile).Result;

        if (mm.VideoCreationTime == null)
        {
            mm.VideoCreationTime = tags.SingleOrDefaultPrimaryTag("CreateDate")?.TryGetDateTime();
        }

        mm.Latitude     = tags.SingleOrDefaultPrimaryTag("GPSLatitude")?.TryGetDouble();
        mm.LatitudeRef  = tags.SingleOrDefaultPrimaryTag("GPSLatitudeRef")?.Value?.Substring(0, 1);
        mm.Longitude    = tags.SingleOrDefaultPrimaryTag("GPSLongitude")?.TryGetDouble();
        mm.LongitudeRef = tags.SingleOrDefaultPrimaryTag("GPSLongitudeRef")?.Value?.Substring(0, 1);
    }
Beispiel #14
0
        internal static MovieViewModel ProjectToViewModel(Movie movie)
        {
            MovieMetadata metadata = Optional(movie.MovieMetadata).Flatten().Head();

            return(new MovieViewModel(
                       metadata.Title,
                       metadata.Year?.ToString(),
                       metadata.Plot,
                       Artwork(metadata, ArtworkKind.Poster),
                       Artwork(metadata, ArtworkKind.FanArt),
                       metadata.Genres.Map(g => g.Name).ToList(),
                       metadata.Tags.Map(t => t.Name).ToList(),
                       metadata.Studios.Map(s => s.Name).ToList()));
        }
Beispiel #15
0
        private async Task <Either <BaseError, MediaItemScanResult <PlexMovie> > > UpdateArtwork(
            MediaItemScanResult <PlexMovie> result,
            PlexMovie incoming)
        {
            PlexMovie     existing         = result.Item;
            MovieMetadata existingMetadata = existing.MovieMetadata.Head();
            MovieMetadata incomingMetadata = incoming.MovieMetadata.Head();

            if (incomingMetadata.DateUpdated > existingMetadata.DateUpdated)
            {
                await UpdateArtworkIfNeeded(existingMetadata, incomingMetadata, ArtworkKind.Poster);
                await UpdateArtworkIfNeeded(existingMetadata, incomingMetadata, ArtworkKind.FanArt);

                await _metadataRepository.MarkAsUpdated(existingMetadata, incomingMetadata.DateUpdated);
            }

            return(result);
        }
        private async Task <MovieMetadata> GetCurrentMetadataAsync(int movieId)
        {
            var model = await this.MovieRepository.GetById(movieId, this.MovieRepository.AllColumnNames);

            var metadata = new MovieMetadata();

            metadata.BackdropUrls      = model.BackdropUrls.ToList();
            metadata.CompletionSeconds = model.CompletionSeconds;
            metadata.PosterUrls        = model.PosterUrls.ToList();
            metadata.Rating            = model.Rating;
            metadata.ReleaseYear       = model.ReleaseYear;
            metadata.RuntimeSeconds    = model.RuntimeSeconds;
            metadata.ShortSummary      = model.ShortSummary;
            metadata.SortTitle         = model.SortTitle;
            metadata.Summary           = model.Summary;
            metadata.Title             = model.Title;
            metadata.TmdbId            = model.TmdbId;

            return(metadata);
        }
        private async Task <Either <BaseError, MediaItemScanResult <Movie> > > UpdateArtwork(
            MediaItemScanResult <Movie> result,
            ArtworkKind artworkKind)
        {
            try
            {
                Movie movie = result.Item;
                await LocateArtwork(movie, artworkKind).IfSomeAsync(
                    async posterFile =>
                {
                    MovieMetadata metadata = movie.MovieMetadata.Head();
                    await RefreshArtwork(posterFile, metadata, artworkKind);
                });

                return(result);
            }
            catch (Exception ex)
            {
                return(BaseError.New(ex.ToString()));
            }
        }
Beispiel #18
0
        private MovieMetadata CreateMetadata()
        {
            MovieMetadata metadata = new MovieMetadata
            {
                Certification   = Certification,
                Credits         = Credits.Collection.ToList(),
                Directors       = Directors.Collection.ToList(),
                FileInformation = FileInformation,
                Genres          = Genres.Collection.ToList(),
                Id               = Id,
                OriginalTitle    = OriginalTitle,
                Outline          = Outline,
                PlayCount        = PlayCount,
                Plot             = Plot,
                Premiered        = PremieredDate,
                Rating           = Rating,
                RuntimeInMinutes = RuntimeInMinutes,
                Country          = Country,
                SetName          = SetName.Value,
                Studio           = Studio,
                Tagline          = Tagline,
                Title            = Title.Value,
                Year             = Year
            };

            metadata.Actors = new List <ActorMetadata>();
            foreach (IActorViewModel actorViewModel in ActorManager.Actors)
            {
                ActorMetadata actor = new ActorMetadata
                {
                    Name      = actorViewModel.Name.Value,
                    Role      = actorViewModel.Role.Value,
                    Thumb     = actorViewModel.ThumbUrl,
                    ThumbPath = actorViewModel.ThumbPath.Path
                };
                metadata.Actors.Add(actor);
            }

            return(metadata);
        }
Beispiel #19
0
    private async Task <Either <BaseError, MediaItemScanResult <Movie> > > UpdateArtwork(
        MediaItemScanResult <Movie> result,
        ArtworkKind artworkKind,
        CancellationToken cancellationToken)
    {
        try
        {
            Movie           movie        = result.Item;
            Option <string> maybeArtwork = LocateArtwork(movie, artworkKind);
            foreach (string posterFile in maybeArtwork)
            {
                MovieMetadata metadata = movie.MovieMetadata.Head();
                await RefreshArtwork(posterFile, metadata, artworkKind, None, None, cancellationToken);
            }

            return(result);
        }
        catch (Exception ex)
        {
            _client.Notify(ex);
            return(BaseError.New(ex.ToString()));
        }
    }
Beispiel #20
0
        private MovieMetadata GetMovieMetadata(string fileName, MovieMetadata metadata)
        {
            try
            {
                const string PATTERN = @"^(.*?)[.\(](\d{4})[.\)].*\.\w+$";
                Match        match   = Regex.Match(fileName, PATTERN);
                if (match.Success)
                {
                    metadata.Title       = match.Groups[1].Value;
                    metadata.Year        = int.Parse(match.Groups[2].Value);
                    metadata.ReleaseDate = new DateTime(int.Parse(match.Groups[2].Value), 1, 1);
                    metadata.Genres      = new List <Genre>();
                    metadata.Tags        = new List <Tag>();
                    metadata.Studios     = new List <Studio>();
                    metadata.DateUpdated = DateTime.UtcNow;
                }
            }
            catch (Exception)
            {
                // ignored
            }

            return(metadata);
        }
Beispiel #21
0
 /// <remarks/>
 public System.IAsyncResult BeginaddAsset(string in0, string in1, string in2, string in3, string in4, string in5, bool in6, NameValue[] in7, MovieMetadata in8, System.AsyncCallback callback, object asyncState) {
     return this.BeginInvoke("addAsset", new object[] {
                 in0,
                 in1,
                 in2,
                 in3,
                 in4,
                 in5,
                 in6,
                 in7,
                 in8}, callback, asyncState);
 }
Beispiel #22
0
 public string addAsset(string in0, string in1, string in2, string in3, string in4, string in5, bool in6, NameValue[] in7, MovieMetadata in8) {
     object[] results = this.Invoke("addAsset", new object[] {
                 in0,
                 in1,
                 in2,
                 in3,
                 in4,
                 in5,
                 in6,
                 in7,
                 in8});
     return ((string)(results[0]));
 }
Beispiel #23
0
 protected override Task <Either <BaseError, MediaItemScanResult <EmbyMovie> > > UpdateMetadata(
     MediaItemScanResult <EmbyMovie> result,
     MovieMetadata fullMetadata) =>
 Task.FromResult <Either <BaseError, MediaItemScanResult <EmbyMovie> > >(result);
        public async Task <MovieMetadata> GetTmdbMetadataAsync(int tmdbId)
        {
            TMDbLib.Objects.Movies.Movie movie = null;
            Directory.CreateDirectory(this.AppSettings.TmdbCacheDirectoryPath);
            var cacheFilePath = $"{this.AppSettings.TmdbCacheDirectoryPath}/{tmdbId}.json";

            //if a cache file exists, and it's was updated less than a month ago, use it.
            if (File.Exists(cacheFilePath) && (DateTime.Now - File.GetLastWriteTime(cacheFilePath)).TotalDays < 30)
            {
                try
                {
                    movie = Newtonsoft.Json.JsonConvert.DeserializeObject <TMDbLib.Objects.Movies.Movie>(File.ReadAllText(cacheFilePath));
                }
                catch (Exception)
                {
                }
            }
            //if the movie could not be loaded from cache, retrieve a fresh copy from TMDB
            if (movie == null)
            {
                //only allow one thread to use the client at a time
                lock (Client)
                {
                    movie = Client.GetMovieAsync(tmdbId,
                                                 MovieMethods.AlternativeTitles |
                                                 MovieMethods.Credits |
                                                 MovieMethods.Images |
                                                 MovieMethods.Keywords |
                                                 MovieMethods.Releases |
                                                 MovieMethods.ReleaseDates |
                                                 MovieMethods.Videos
                                                 ).Result;
                }
                //save this result to disc
                var camelCaseFormatter = new JsonSerializerSettings();
                camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver();
                camelCaseFormatter.Formatting       = Formatting.Indented;

                var json = Newtonsoft.Json.JsonConvert.SerializeObject(movie, camelCaseFormatter);
                await File.WriteAllTextAsync(cacheFilePath, json);
            }

            var metadata = new MovieMetadata();

            metadata.AddCast(movie.Credits?.Cast);
            metadata.AddCrew(movie.Credits?.Crew);
            metadata.Collection = movie.BelongsToCollection?.Name;
            metadata.Summary    = movie.Overview;
            metadata.Genres     = movie.Genres?.Select(x => x.Name).ToList();
            metadata.Keywords   = movie.Keywords?.Keywords?.Select(x => x.Name).ToList();
            var release = movie.Releases?.Countries
                          ?.Where(x => x.Iso_3166_1.ToLower() == "us")
                          ?.OrderBy(x => x.ReleaseDate)
                          ?.First();

            //get the oldest US rating
            metadata.Rating      = release?.Certification;
            metadata.ReleaseYear = release?.ReleaseDate?.Year;
            //conver the runtime to seconds
            metadata.RuntimeSeconds = movie.Runtime * 60;
            metadata.Summary        = movie.Overview;
            metadata.Title          = movie.Title;
            metadata.SortTitle      = movie.Title;

            metadata.ExtraSearchText.AddRange(
                movie.AlternativeTitles?.Titles?.Where(x => x.Iso_3166_1.ToLower() == "us").Select(x => x.Title).ToList() ?? new List <string>()
                );
            metadata.ExtraSearchText.Add(movie.OriginalTitle);

            metadata.ExtraSearchText = metadata.ExtraSearchText.Distinct().ToList();

            metadata.TmdbId = movie.Id;


            if (movie.PosterPath != null)
            {
                metadata.PosterUrls.Add(Client.GetImageUrl("original", movie.PosterPath).ToString());
            }
            metadata.PosterUrls.AddRange(
                movie.Images?.Posters
                ?.Where(x => x.Iso_639_1?.ToLower() == "en")
                ?.Select(x => Client.GetImageUrl("original", x.FilePath).ToString())
                ?.ToList() ?? new List <string>()
                );
            metadata.PosterUrls = metadata.PosterUrls.Distinct().ToList();


            //add the marked backdrop path first
            if (movie.BackdropPath != null)
            {
                metadata.BackdropUrls.Add(Client.GetImageUrl("original", movie.BackdropPath).ToString());
            }
            //add all additional backdrops
            metadata.BackdropUrls.AddRange(
                movie.Images?.Backdrops
                //move the highest rated backdrops to the top
                ?.OrderByDescending(x => x.VoteAverage)
                ?.Where(x => x.Iso_639_1?.ToLower() == "en" || x.Iso_639_1 == null)
                ?.Select(x => Client.GetImageUrl("original", x.FilePath).ToString())
                ?.ToList() ?? new List <string>()
                );
            metadata.BackdropUrls = metadata.BackdropUrls.Distinct().ToList();
            return(metadata);
        }
Beispiel #25
0
    void GenerateThumbSq(Ffmpeg ffmpeg, string localSourceFile, string localThumbSqFile, MovieMetadata mm)
    {
        ffmpeg.ExtractFrame(localSourceFile, localThumbSqFile, GetThumbnailSeconds(mm));

        using (var wand = new MagickWand(localThumbSqFile))
        {
            var width  = (double)wand.ImageWidth;
            var height = (double)wand.ImageHeight;
            var aspect = width / height;

            if (aspect >= THUMB_SQ_ASPECT)
            {
                var newWidth = (width / height) * THUMB_SQ_HEIGHT;

                // scale image to final height
                wand.ScaleImage((uint)newWidth, THUMB_SQ_HEIGHT);

                // crop sides as needed
                wand.CropImage(THUMB_SQ_WIDTH, THUMB_SQ_HEIGHT, (int)(newWidth - THUMB_SQ_WIDTH) / 2, 0);
            }
            else
            {
                var newHeight = THUMB_SQ_WIDTH / (width / height);

                // scale image to final width
                wand.ScaleImage(THUMB_SQ_WIDTH, (uint)newHeight);

                // crop top and bottom as needed
                wand.CropImage(THUMB_SQ_WIDTH, THUMB_SQ_HEIGHT, 0, (int)(newHeight - THUMB_SQ_HEIGHT) / 2);
            }

            // sharpen after potentially resizing
            // http://www.imagemagick.org/Usage/resize/#resize_unsharp
            wand.UnsharpMaskImage(0, 0.7, 0.7, 0.008);

            wand.WriteImage(localThumbSqFile, true);

            mm.ThumbSqHeight = THUMB_SQ_HEIGHT;
            mm.ThumbSqWidth  = THUMB_SQ_WIDTH;
        }
    }
Beispiel #26
0
    void GenerateThumbnail(Ffmpeg ffmpeg, string localSourceFile, string localThumbnailFile, MovieMetadata mm)
    {
        ffmpeg.ExtractFrame(localSourceFile, localThumbnailFile, GetThumbnailSeconds(mm));

        using (var wand = new MagickWand(localThumbnailFile))
        {
            wand.GetLargestDimensionsKeepingAspectRatio(THUMB_WIDTH, THUMB_HEIGHT, out uint width, out uint height);
            wand.ScaleImage(width, height);

            // sharpen after potentially resizing
            // http://www.imagemagick.org/Usage/resize/#resize_unsharp
            wand.UnsharpMaskImage(0, 0.7, 0.7, 0.008);

            wand.WriteImage(localThumbnailFile, true);

            mm.ThumbHeight = (int)height;
            mm.ThumbWidth  = (int)width;
        }
    }
Beispiel #27
0
    void ProcessMovie(string movie)
    {
        Console.WriteLine($"Processing: {Path.GetFileName(movie)}");

        Ffmpeg ffmpeg = new FfmpegH264();

        MovieMetadata mm              = ffmpeg.GatherMetadata(movie);
        var           fullDimension   = new ScaledDimensions(FULL_MIN_DIMENSION, mm.RawHeight, mm.RawWidth);
        var           scaledDimension = new ScaledDimensions(SCALE_MIN_DIMENSION, mm.RawHeight, mm.RawWidth);

        var dir       = Path.GetDirectoryName(movie);
        var file      = Path.GetFileName(movie);
        var fileOut   = $"{Path.GetFileNameWithoutExtension(movie)}{ffmpeg.OutputFileExtension}";
        var fileThumb = $"{Path.GetFileNameWithoutExtension(movie)}.jpg";

        var localRawFile       = Path.Combine(dir, DIR_RAW, file);
        var localFullFile      = Path.Combine(dir, DIR_FULL, fileOut);
        var localScaledFile    = Path.Combine(dir, DIR_SCALED, fileOut);
        var localThumbnailFile = Path.Combine(dir, DIR_THUMBNAILS, fileThumb);
        var localThumbSqFile   = Path.Combine(dir, DIR_THUMB_SQ, fileThumb);

        // move the raw file
        mm.RawUrl = Path.Combine(WebRawDirectory, file);
        File.Move(movie, localRawFile);
        mm.RawSize = GetFileSize(localRawFile);

        // convert for full size
        mm.FullHeight = fullDimension.ScaledHeight;
        mm.FullWidth  = fullDimension.ScaledWidth;
        mm.FullUrl    = Path.Combine(WebFullsizeDirectory, fileOut);
        ffmpeg.Convert(localRawFile, localFullFile, mm.FullWidth, mm.FullHeight);
        mm.FullSize = GetFileSize(localFullFile);

        // some sources seem to report bad durations - but the webm conversions seem clean, so use those to get the duration!
        MovieMetadata m2 = ffmpeg.GatherMetadata(localFullFile);

        mm.VideoDuration = m2.VideoDuration;

        // convert to scaled size
        mm.ScaledHeight = scaledDimension.ScaledHeight;
        mm.ScaledWidth  = scaledDimension.ScaledWidth;
        mm.ScaledUrl    = Path.Combine(WebScaledDirectory, fileOut);
        ffmpeg.Convert(localRawFile, localScaledFile, mm.ScaledWidth, mm.ScaledHeight);
        mm.ScaledSize = GetFileSize(localScaledFile);

        // generate thumbnail
        mm.ThumbUrl = Path.Combine(WebThumbnailDirectory, fileThumb);
        GenerateThumbnail(ffmpeg, localRawFile, localThumbnailFile, mm);
        mm.ThumbSize = GetFileSize(localThumbnailFile);

        // generate thumb_sq
        mm.ThumbSqUrl = Path.Combine(WebThumbSqDirectory, fileThumb);
        GenerateThumbSq(ffmpeg, localRawFile, localThumbSqFile, mm);
        mm.ThumbSqSize = GetFileSize(localThumbSqFile);

        PopulateVideoMetadata(localRawFile, mm);

        lock (_lockObj)
        {
            Writer.WriteLine(
                "INSERT INTO video.video (category_id, " +
                $"thumb_height, thumb_width, thumb_path, thumb_size, " +
                $"thumb_sq_height, thumb_sq_width, thumb_sq_path, thumb_sq_size, " +
                $"full_height, full_width, full_path, full_size, " +
                $"scaled_height, scaled_width, scaled_path, scaled_size, " +
                $"raw_height, raw_width, raw_path, raw_size, " +
                $"duration, create_date, " +
                $"gps_latitude, gps_latitude_ref_id, gps_longitude, gps_longitude_ref_id) VALUES (" +
                $"(SELECT currval('video.category_id_seq')), " +
                $"{mm.ThumbHeight}, " +
                $"{mm.ThumbWidth}, " +
                $"{SqlString(mm.ThumbUrl)}, " +
                $"{mm.ThumbSize}, " +
                $"{mm.ThumbSqHeight}, " +
                $"{mm.ThumbSqWidth}, " +
                $"{SqlString(mm.ThumbSqUrl)}, " +
                $"{mm.ThumbSqSize}, " +
                $"{mm.FullHeight}, " +
                $"{mm.FullWidth}, " +
                $"{SqlString(mm.FullUrl)}, " +
                $"{mm.FullSize}, " +
                $"{mm.ScaledHeight}, " +
                $"{mm.ScaledWidth}, " +
                $"{SqlString(mm.ScaledUrl)}, " +
                $"{mm.ScaledSize}, " +
                $"{mm.RawHeight}, " +
                $"{mm.RawWidth}, " +
                $"{SqlString(mm.RawUrl)}, " +
                $"{mm.RawSize}, " +
                $"{SqlNumber(mm.VideoDuration)}, " +
                $"{SqlTimestamp(mm.VideoCreationTime)}, " +
                $"{SqlNumber(mm.Latitude)}, " +
                $"{SqlString(mm.LatitudeRef)}, " +
                $"{SqlNumber(mm.Longitude)}, " +
                $"{SqlString(mm.LongitudeRef)} " +
                $");");

            if (!HasSetTeaserVideo)
            {
                Writer.WriteLine();
                Writer.WriteLine(
                    $"UPDATE video.category " +
                    $"   SET teaser_image_path = {SqlString(mm.ThumbUrl)}, " +
                    $"       teaser_image_height = {mm.ThumbHeight}, " +
                    $"       teaser_image_width = {mm.ThumbWidth}, " +
                    $"       teaser_image_size = {mm.ThumbSize}, " +
                    $"       teaser_image_sq_path = {SqlString(mm.ThumbSqUrl)}, " +
                    $"       teaser_image_sq_height = {mm.ThumbSqHeight}, " +
                    $"       teaser_image_sq_width = {mm.ThumbSqWidth}, " +
                    $"       teaser_image_sq_size = {mm.ThumbSqSize} " +
                    $" WHERE id = (SELECT currval('video.category_id_seq'));");
                Writer.WriteLine();

                HasSetTeaserVideo = true;
            }
        }
    }
Beispiel #28
0
        public async Task ProcessExistingMovie(MovieMetadata metadata = null)
        {
            var record = new DynamicParameters();

            //this is an existing movie. Fetch its id
            await this.LoadId();

            //if we have metadata, use that info
            if (metadata != null)
            {
                record.Add("title", metadata.Title);
                record.Add("sortTitle", metadata.SortTitle);
                record.Add("rating", metadata.Rating);
                record.Add("releaseYear", metadata.ReleaseYear);
                record.Add("summary", metadata.Summary);
                record.Add("tmdbId", metadata.TmdbId);
            }

            List <string> posterUrls = null;

            if (metadata != null && metadata.PosterUrls.Count() > 0)
            {
                posterUrls = metadata.PosterUrls;
            }
            else if (PosterPathsFromFileSystem.Count() > 0)
            {
                posterUrls = PosterPathsFromFileSystem.ToList();
            }
            else
            {
                // leave posters the way they are.
            }

            //only copy posters if we have a list of urls to copy
            if (posterUrls != null)
            {
                var posterCount = await CopyImages(posterUrls, this.PosterFolderPath, ImageType.Poster);

                record.Add("posterCount", posterCount);
            }

            List <string> backdropUrls = null;

            if (metadata != null && metadata.BackdropUrls.Count() > 0)
            {
                backdropUrls = metadata.BackdropUrls;
            }
            else if (PosterPathsFromFileSystem.Count() > 0)
            {
                backdropUrls = BackdropPathsFromFileSystem.ToList();
            }
            else
            {
                // leave backdrops the way they are.
            }

            //only copy backdrops if we have a list of backdrops to copy
            if (backdropUrls != null)
            {
                var backdropCount = await CopyImages(backdropUrls, this.BackdropFolderPath, ImageType.Backdrop);

                record.Add("backdropCount", backdropCount);
            }

            record.Add("id", this.Id);
            record.Add("folderPath", this.FolderPath);
            record.Add("videoPath", this.VideoPath);
            record.Add("runtimeSeconds", this.GetRuntimeSeconds());
            record.Add("sourceId", this.SourceId);

            //update the db with all of the fields we collected
            Console.WriteLine($"Update db record: {this.FolderPath}");
            await this.LibGenMovieRepository.Update(record);
        }
Beispiel #29
0
        public string ToXml()
        {
            using var ms  = new MemoryStream();
            using var xml = XmlWriter.Create(ms);
            xml.WriteStartDocument();

            xml.WriteStartElement("tv");
            xml.WriteAttributeString("generator-info-name", "ersatztv");

            foreach (Channel channel in _channels.OrderBy(c => c.Number))
            {
                xml.WriteStartElement("channel");
                xml.WriteAttributeString("id", channel.Number);

                xml.WriteStartElement("display-name");
                xml.WriteAttributeString("lang", "en");
                xml.WriteString(channel.Name);
                xml.WriteEndElement(); // display-name

                xml.WriteStartElement("icon");
                string logo = Optional(channel.Artwork).Flatten()
                              .Filter(a => a.ArtworkKind == ArtworkKind.Logo)
                              .HeadOrNone()
                              .Match(
                    artwork => $"{_scheme}://{_host}/iptv/logos/{artwork.Path}",
                    () => $"{_scheme}://{_host}/images/ersatztv-500.png");
                xml.WriteAttributeString("src", logo);
                xml.WriteEndElement(); // icon

                xml.WriteEndElement(); // channel
            }

            foreach (Channel channel in _channels.OrderBy(c => c.Number))
            {
                foreach (PlayoutItem playoutItem in channel.Playouts.Collect(p => p.Items).OrderBy(i => i.Start))
                {
                    string start = playoutItem.StartOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty);
                    string stop  = playoutItem.FinishOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty);

                    string title = playoutItem.MediaItem switch
                    {
                        Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Title ?? string.Empty)
                        .IfNone("[unknown movie]"),
                        Episode e => e.Season.Show.ShowMetadata.HeadOrNone().Map(em => em.Title ?? string.Empty)
                        .IfNone("[unknown show]"),
                        _ => "[unknown]"
                    };

                    string subtitle = playoutItem.MediaItem switch
                    {
                        Episode e => e.EpisodeMetadata.HeadOrNone().Match(
                            em => em.Title ?? string.Empty,
                            () => string.Empty),
                        _ => string.Empty
                    };

                    string description = playoutItem.MediaItem switch
                    {
                        Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Plot ?? string.Empty).IfNone(string.Empty),
                        Episode e => e.EpisodeMetadata.HeadOrNone().Map(em => em.Plot ?? string.Empty)
                        .IfNone(string.Empty),
                        _ => string.Empty
                    };

                    string contentRating = playoutItem.MediaItem switch
                    {
                        // TODO: re-implement content rating
                        // Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.ContentRating).IfNone(string.Empty),
                        _ => string.Empty
                    };

                    xml.WriteStartElement("programme");
                    xml.WriteAttributeString("start", start);
                    xml.WriteAttributeString("stop", stop);
                    xml.WriteAttributeString("channel", channel.Number);

                    if (playoutItem.MediaItem is Movie movie)
                    {
                        xml.WriteStartElement("category");
                        xml.WriteAttributeString("lang", "en");
                        xml.WriteString("Movie");
                        xml.WriteEndElement(); // category

                        Option <MovieMetadata> maybeMetadata = movie.MovieMetadata.HeadOrNone();
                        if (maybeMetadata.IsSome)
                        {
                            MovieMetadata metadata = maybeMetadata.ValueUnsafe();

                            if (metadata.Year.HasValue)
                            {
                                xml.WriteStartElement("date");
                                xml.WriteString(metadata.Year.Value.ToString());
                                xml.WriteEndElement(); // date
                            }

                            string poster = Optional(metadata.Artwork).Flatten()
                                            .Filter(a => a.ArtworkKind == ArtworkKind.Poster)
                                            .HeadOrNone()
                                            .Match(
                                artwork => $"{_scheme}://{_host}/artwork/posters/{artwork.Path}",
                                () => string.Empty);

                            if (!string.IsNullOrWhiteSpace(poster))
                            {
                                xml.WriteStartElement("icon");
                                xml.WriteAttributeString("src", poster);
                                xml.WriteEndElement(); // icon
                            }
                        }
                    }

                    xml.WriteStartElement("title");
                    xml.WriteAttributeString("lang", "en");
                    xml.WriteString(title);
                    xml.WriteEndElement(); // title

                    if (!string.IsNullOrWhiteSpace(subtitle))
                    {
                        xml.WriteStartElement("sub-title");
                        xml.WriteAttributeString("lang", "en");
                        xml.WriteString(subtitle);
                        xml.WriteEndElement(); // subtitle
                    }

                    xml.WriteStartElement("previously-shown");
                    xml.WriteEndElement(); // previously-shown

                    if (playoutItem.MediaItem is Episode episode)
                    {
                        Option <ShowMetadata> maybeMetadata =
                            Optional(episode.Season?.Show?.ShowMetadata.HeadOrNone()).Flatten();
                        if (maybeMetadata.IsSome)
                        {
                            ShowMetadata metadata = maybeMetadata.ValueUnsafe();
                            string       poster   = Optional(metadata.Artwork).Flatten()
                                                    .Filter(a => a.ArtworkKind == ArtworkKind.Poster)
                                                    .HeadOrNone()
                                                    .Match(
                                artwork => $"{_scheme}://{_host}/artwork/posters/{artwork.Path}",
                                () => string.Empty);

                            if (!string.IsNullOrWhiteSpace(poster))
                            {
                                xml.WriteStartElement("icon");
                                xml.WriteAttributeString("src", poster);
                                xml.WriteEndElement(); // icon
                            }
                        }

                        int s = Optional(episode.Season?.SeasonNumber).IfNone(0);
                        int e = episode.EpisodeNumber;
                        if (s > 0 && e > 0)
                        {
                            xml.WriteStartElement("episode-num");
                            xml.WriteAttributeString("system", "onscreen");
                            xml.WriteString($"S{s:00}E{e:00}");
                            xml.WriteEndElement(); // episode-num

                            xml.WriteStartElement("episode-num");
                            xml.WriteAttributeString("system", "xmltv_ns");
                            xml.WriteString($"{s - 1}.{e - 1}.0/1");
                            xml.WriteEndElement(); // episode-num
                        }
                    }

                    // sb.AppendLine("<icon src=\"\"/>");

                    if (!string.IsNullOrWhiteSpace(description))
                    {
                        xml.WriteStartElement("desc");
                        xml.WriteAttributeString("lang", "en");
                        xml.WriteString(description);
                        xml.WriteEndElement(); // desc
                    }

                    if (!string.IsNullOrWhiteSpace(contentRating))
                    {
                        xml.WriteStartElement("rating");
                        xml.WriteAttributeString("system", "MPAA");
                        xml.WriteStartElement("value");
                        xml.WriteString(contentRating);
                        xml.WriteEndElement(); // value
                        xml.WriteEndElement(); // rating
                    }

                    xml.WriteEndElement(); // programme
                }
            }

            xml.WriteEndElement(); // tv
            xml.WriteEndDocument();

            xml.Flush();
            return(Encoding.UTF8.GetString(ms.ToArray()));
        }
    }
}
Beispiel #30
0
        private void btnImport_Click(object sender, System.EventArgs e)
        {
            if (txtPathToFile.Text.Length == 0)
            {
                System.Windows.Forms.MessageBox.Show("Enter the path to an existing MPEG Asset.");
                txtPathToFile.Focus();
                return;
            }
            if (txtName.Text.Length == 0)
            {
                //System.Windows.Forms.MessageBox.Show("Enter a valid Name for the MPEG Asset.");
                //return;
                string[] spl = txtPathToFile.Text.Split(new char[] {'/'});
                string ss = spl[spl.Length - 1];
                txtName.Text = ss.Substring(0,ss.LastIndexOf(".mpg"));
            }
            if (cboAssetGroups.SelectedIndex == -1)
            {
                System.Windows.Forms.MessageBox.Show("Select an Asset Group.");
                cboAssetGroups.Focus();
                return;
            }
            if (cboEncodingType.SelectedIndex == -1)
            {
                System.Windows.Forms.MessageBox.Show("Select an Encoding Type.");
                cboEncodingType.Focus();
                return;
            }

            NameValue[] nv = new NameValue[0];
            MovieMetadata mmd = new MovieMetadata();
            string sId = m_jglue.addAsset(m_sSession,txtName.Text,cboAssetGroups.SelectedItem.ToString(),
                cboEncodingType.SelectedItem.ToString(),txtPathToFile.Text,"",false,nv,mmd);

            m_Parent.statusBar1.Panels[0].Text = "Import complete...";
            m_Parent.RefreshAssetList();
        }
 public async Task <IActionResult> SaveMovieMetadata(MovieMetadata movieData)
 {
     return(Ok(await _movieService.SaveMovieMetaData(movieData)));
 }
Beispiel #32
0
 public async Task <MovieMetadata> SaveMovieMetaData(MovieMetadata movieData)
 {
     this.Database.Append(movieData);
     return(await Task.FromResult(movieData));
 }
 protected abstract Task <Either <BaseError, MediaItemScanResult <TMovie> > > UpdateMetadata(
     MediaItemScanResult <TMovie> result,
     MovieMetadata fullMetadata);