Exemple #1
0
        public Task DeleteSubtitles(string itemId, int index)
        {
            var stream = _mediaSourceManager.GetMediaStreams(new MediaStreamQuery
            {
                Index  = index,
                ItemId = new Guid(itemId),
                Type   = MediaStreamType.Subtitle
            }).First();

            var path = stream.Path;

            _monitor.ReportFileSystemChangeBeginning(path);

            try
            {
                _fileSystem.DeleteFile(path);
            }
            finally
            {
                _monitor.ReportFileSystemChangeComplete(path, false);
            }

            return(_libraryManager.GetItemById(itemId).RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem))
            {
                ImageRefreshMode = ImageRefreshMode.ValidationOnly,
                MetadataRefreshMode = MetadataRefreshMode.ValidationOnly
            }, CancellationToken.None));
        }
Exemple #2
0
        public Task DeleteSubtitles(string itemId, int index)
        {
            var stream = _mediaSourceManager.GetMediaStreams(new MediaStreamQuery
            {
                Index  = index,
                ItemId = new Guid(itemId),
                Type   = MediaStreamType.Subtitle
            }).First();

            var path = stream.Path;

            _monitor.ReportFileSystemChangeBeginning(path);

            try
            {
                _fileSystem.DeleteFile(path);
            }
            finally
            {
                _monitor.ReportFileSystemChangeComplete(path, false);
            }

            _libraryManager.GetItemById(itemId).ChangedExternally();
            return(Task.FromResult(true));
        }
Exemple #3
0
        private async Task <DynamicImageResponse> GetVideoImage(Video item, CancellationToken cancellationToken)
        {
            MediaSourceInfo mediaSource = new MediaSourceInfo
            {
                VideoType = item.VideoType,
                IsoType   = item.IsoType,
                Protocol  = item.PathProtocol ?? MediaProtocol.File,
            };

            // If we know the duration, grab it from 10% into the video. Otherwise just 10 seconds in.
            // Always use 10 seconds for dvd because our duration could be out of whack
            var imageOffset = item.VideoType != VideoType.Dvd && item.RunTimeTicks > 0
                                  ? TimeSpan.FromTicks(item.RunTimeTicks.Value / 10)
                                  : TimeSpan.FromSeconds(10);

            var query = new MediaStreamQuery {
                ItemId = item.Id, Index = item.DefaultVideoStreamIndex
            };
            var videoStream = _mediaSourceManager.GetMediaStreams(query).FirstOrDefault();

            if (videoStream == null)
            {
                query.Type  = MediaStreamType.Video;
                query.Index = null;
                videoStream = _mediaSourceManager.GetMediaStreams(query).FirstOrDefault();
            }

            if (videoStream == null)
            {
                _logger.LogInformation("Skipping image extraction: no video stream found for {Path}.", item.Path ?? string.Empty);
                return(new DynamicImageResponse {
                    HasImage = false
                });
            }

            string extractedImagePath = await _mediaEncoder.ExtractVideoImage(item.Path, item.Container, mediaSource, videoStream, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);

            return(new DynamicImageResponse
            {
                Format = ImageFormat.Jpg,
                HasImage = true,
                Path = extractedImagePath,
                Protocol = MediaProtocol.File
            });
        }
Exemple #4
0
        public Task <DynamicImageResponse> GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken)
        {
            var imageStreams = _mediaSourceManager.GetMediaStreams(new MediaStreamQuery
            {
                ItemId = item.Id,
                Type   = MediaStreamType.EmbeddedImage
            });

            // Can't extract if we didn't find a video stream in the file
            if (imageStreams.Count == 0)
            {
                return(Task.FromResult(new DynamicImageResponse {
                    HasImage = false
                }));
            }

            return(GetImage((Audio)item, imageStreams, cancellationToken));
        }
Exemple #5
0
        public Task DeleteSubtitles(BaseItem item, int index)
        {
            var stream = _mediaSourceManager.GetMediaStreams(new MediaStreamQuery
            {
                Index  = index,
                ItemId = item.Id,
                Type   = MediaStreamType.Subtitle
            })[0];

            var path = stream.Path;

            _monitor.ReportFileSystemChangeBeginning(path);

            try
            {
                _fileSystem.DeleteFile(path);
            }
            finally
            {
                _monitor.ReportFileSystemChangeComplete(path, false);
            }

            return(item.RefreshMetadata(CancellationToken.None));
        }
Exemple #6
0
        public async Task <ChannelItemResult> GetItems(bool inChannel, InternalChannelItemQuery query, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var config = await BlurNTasks.CheckIfResetDatabaseRequested(cancellationToken, _json, _appPaths, _fileSystem).ConfigureAwait(false);

            if (inChannel)
            {
                Plugin.DebugLogger("Entered BlurN channel list");
            }

            User user = query.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(query.UserId);

            Dictionary <string, BaseItem> libDict = (user == null) ? new Dictionary <string, BaseItem>() : Library.BuildLibraryDictionary(cancellationToken, _libraryManager, new InternalItemsQuery()
            {
                HasAnyProviderId = new[] { "Imdb" },
                User             = user,
                //SourceTypes = new SourceType[] { SourceType.Library }
            });

            Plugin.DebugLogger($"Found {libDict.Count} items in movies library");

            BlurNItems items    = new BlurNItems();
            string     dataPath = Path.Combine(_appPaths.PluginConfigurationsPath, "MediaBrowser.Channels.BlurN.Data.json");

            if (_fileSystem.FileExists(dataPath))
            {
                items.List = _json.DeserializeFromFile <List <BlurNItem> >(dataPath);
            }

            if (inChannel)
            {
                Plugin.DebugLogger("Retrieved items");
            }

            if (items == null)
            {
                if (inChannel)
                {
                    Plugin.DebugLogger("Items is null, set to new list");
                }
                items = new BlurNItems();
                Plugin.Instance.SaveConfiguration();
            }

            for (int i = 0; i < items.List.Count; i++)
            {
                BlurNItem blurNItem = items.List[i];

                BaseItem libraryItem;
                bool     foundInLibrary = libDict.TryGetValue(blurNItem.ImdbId, out libraryItem);
                if (foundInLibrary)
                {
                    if (config.HidePlayedMovies && user != null && libraryItem.IsPlayed(user))
                    {
                        items.List.RemoveAt(i);
                        i--;
                        if (inChannel)
                        {
                            Plugin.DebugLogger($"Hiding movie '{blurNItem.Title}' from BlurN channel list as watched by user");
                        }
                    }
                    else if (!config.AddItemsAlreadyInLibrary)
                    {
                        items.List.RemoveAt(i);
                        i--;
                        if (inChannel)
                        {
                            Plugin.DebugLogger($"Hiding movie '{blurNItem.Title}' from BlurN channel list as availabile in library");
                        }
                    }
                    else
                    {
                        blurNItem.LibraryItem = libraryItem;
                    }
                }
            }

            switch (query.SortBy)
            {
            case ChannelItemSortField.Name:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.Title);
                }
                else
                {
                    items.List.OrderBy(i => i.Title);
                }
                break;

            case ChannelItemSortField.DateCreated:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.BluRayReleaseDate);
                }
                else
                {
                    items.List.OrderBy(i => i.BluRayReleaseDate);
                }
                break;

            case ChannelItemSortField.CommunityRating:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.ImdbRating).ThenByDescending(i => i.ImdbVotes);
                }
                else
                {
                    items.List.OrderBy(i => i.ImdbRating).ThenBy(i => i.ImdbVotes);
                }
                break;

            case ChannelItemSortField.PremiereDate:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.Released);
                }
                else
                {
                    items.List.OrderBy(i => i.Released);
                }
                break;

            case ChannelItemSortField.Runtime:
                if (query.SortDescending)
                {
                    items.List.OrderByDescending(i => i.RuntimeTicks);
                }
                else
                {
                    items.List.OrderBy(i => i.RuntimeTicks);
                }
                break;

            default:
                if (query.SortDescending)
                {
                    items.List.Reverse();
                }
                break;
            }

            BlurNItems showList = new BlurNItems();

            if (query.StartIndex.HasValue && query.Limit.HasValue && query.Limit.Value > 0)
            {
                int index = query.StartIndex.Value;
                int limit = query.Limit.Value;

                if (items.List.Count < index + limit)
                {
                    limit = items.List.Count - index;
                }

                showList.List = items.List.GetRange(index, limit);
                if (inChannel)
                {
                    Plugin.DebugLogger($"Showing range with index {index} and limit {limit}");
                }
            }
            else
            {
                showList.List = items.List;
                if (inChannel)
                {
                    Plugin.DebugLogger("Showing full list");
                }
            }

            ChannelItemResult result = new ChannelItemResult()
            {
                TotalRecordCount = items.List.Count
            };

            for (int i = 0; i < showList.List.Count; i++)
            {
                BlurNItem blurNItem = showList.List[i];

                if (inChannel)
                {
                    Plugin.DebugLogger($"Showing movie '{blurNItem.Title}' to BlurN channel list");
                }

                var directors = CSVParse(blurNItem.Director);
                var writers   = CSVParse(blurNItem.Writer);
                var actors    = CSVParse(blurNItem.Actors);

                var people = new List <PersonInfo>();
                foreach (var director in directors)
                {
                    people.Add(new PersonInfo()
                    {
                        Name = director, Role = "Director"
                    });
                }
                foreach (var writer in writers)
                {
                    people.Add(new PersonInfo()
                    {
                        Name = writer, Role = "Writer"
                    });
                }
                foreach (string actor in actors)
                {
                    people.Add(new PersonInfo()
                    {
                        Name = actor, Role = "Actor"
                    });
                }

                var genres = CSVParse(blurNItem.Genre).ToList();

                var cii = new ChannelItemInfo()
                {
                    Id              = $"{config.ChannelRefreshCount.ToString()}-{blurNItem.ImdbId}",
                    IndexNumber     = i,
                    CommunityRating = (float)blurNItem.ImdbRating,
                    ContentType     = ChannelMediaContentType.Movie,
                    DateCreated     = blurNItem.BluRayReleaseDate,
                    Genres          = genres,
                    ImageUrl        = (blurNItem.Poster == "N/A") ? null : blurNItem.Poster,
                    MediaType       = ChannelMediaType.Video,
                    Name            = blurNItem.Title,
                    OfficialRating  = (blurNItem.Rated == "N/A") ? null : blurNItem.Rated,
                    Overview        = (blurNItem.Plot == "N/A") ? null : blurNItem.Plot,
                    People          = people,
                    PremiereDate    = blurNItem.Released,
                    ProductionYear  = blurNItem.Released.Year,
                    RunTimeTicks    = blurNItem.RuntimeTicks,
                    Type            = ChannelItemType.Media,
                    DateModified    = blurNItem.BluRayReleaseDate,
                    IsLiveStream    = false
                };

                cii.SetProviderId(MetadataProviders.Imdb, blurNItem.ImdbId);
                if (blurNItem.TmdbId.HasValue)
                {
                    cii.SetProviderId(MetadataProviders.Tmdb, blurNItem.TmdbId.Value.ToString());
                }

                if (blurNItem.LibraryItem != null)
                {
                    var mediaStreams = _mediaSourceManager.GetMediaStreams(blurNItem.LibraryItem.InternalId).ToList();

                    var audioStream = mediaStreams.FirstOrDefault(ms => ms.Type == MediaStreamType.Audio && ms.IsDefault);
                    var videoStream = mediaStreams.FirstOrDefault(ms => ms.Type == MediaStreamType.Video && ms.IsDefault);

                    ChannelMediaInfo cmi = new ChannelMediaInfo()
                    {
                        Path               = _libraryManager.GetPathAfterNetworkSubstitution(blurNItem.LibraryItem.Path, blurNItem.LibraryItem),
                        Container          = blurNItem.LibraryItem.Container,
                        RunTimeTicks       = blurNItem.LibraryItem.RunTimeTicks,
                        SupportsDirectPlay = true,
                        Id       = blurNItem.LibraryItem.Id.ToString(),
                        Protocol = Model.MediaInfo.MediaProtocol.File
                    };

                    if (audioStream != null)
                    {
                        cmi.AudioBitrate    = audioStream.BitRate;
                        cmi.AudioChannels   = audioStream.Channels;
                        cmi.AudioCodec      = audioStream.Codec;
                        cmi.AudioSampleRate = audioStream.SampleRate;
                    }
                    if (videoStream != null)
                    {
                        cmi.Framerate    = videoStream.RealFrameRate;
                        cmi.Height       = videoStream.Height;
                        cmi.IsAnamorphic = videoStream.IsAnamorphic;
                        cmi.VideoBitrate = videoStream.BitRate;
                        cmi.VideoCodec   = videoStream.Codec;
                        if (videoStream.Level.HasValue)
                        {
                            cmi.VideoLevel = (float)videoStream.Level.Value;
                        }
                        cmi.VideoProfile = videoStream.Profile;
                        cmi.Width        = videoStream.Width;
                    }
                    Plugin.DebugLogger($"Linked movie {blurNItem.Title} to library. Path: {blurNItem.LibraryItem.Path}, Substituted Path: {cmi.Path}");
                    cii.MediaSources = new List <MediaSourceInfo>()
                    {
                        cmi.ToMediaSource()
                    };
                }

                result.Items.Add(cii);

                if (inChannel)
                {
                    Plugin.DebugLogger($"Added movie '{blurNItem.Title}' to BlurN channel list");
                }
            }

            if (inChannel)
            {
                Plugin.DebugLogger($"Set total record count ({(int)result.TotalRecordCount})");
            }

            return(result);
        }
        private async Task <DynamicImageResponse> GetEmbeddedImage(Video item, ImageType type, CancellationToken cancellationToken)
        {
            MediaSourceInfo mediaSource = new MediaSourceInfo
            {
                VideoType = item.VideoType,
                IsoType   = item.IsoType,
                Protocol  = item.PathProtocol ?? MediaProtocol.File,
            };

            string[] imageFileNames = type switch
            {
                ImageType.Primary => _primaryImageFileNames,
                ImageType.Backdrop => _backdropImageFileNames,
                ImageType.Logo => _logoImageFileNames,
                _ => Array.Empty <string>()
            };

            if (imageFileNames.Length == 0)
            {
                _logger.LogWarning("Attempted to load unexpected image type: {Type}", type);
                return(new DynamicImageResponse {
                    HasImage = false
                });
            }

            // Try attachments first
            var attachmentStream = _mediaSourceManager.GetMediaAttachments(item.Id)
                                   .FirstOrDefault(attachment => !string.IsNullOrEmpty(attachment.FileName) &&
                                                   imageFileNames.Any(name => attachment.FileName.Contains(name, StringComparison.OrdinalIgnoreCase)));

            if (attachmentStream != null)
            {
                return(await ExtractAttachment(item, attachmentStream, mediaSource, cancellationToken));
            }

            // Fall back to EmbeddedImage streams
            var imageStreams = _mediaSourceManager.GetMediaStreams(new MediaStreamQuery
            {
                ItemId = item.Id,
                Type   = MediaStreamType.EmbeddedImage
            });

            if (imageStreams.Count == 0)
            {
                // Can't extract if we don't have any EmbeddedImage streams
                return(new DynamicImageResponse {
                    HasImage = false
                });
            }

            // Extract first stream containing an element of imageFileNames
            var imageStream = imageStreams
                              .FirstOrDefault(stream => !string.IsNullOrEmpty(stream.Comment) &&
                                              imageFileNames.Any(name => stream.Comment.Contains(name, StringComparison.OrdinalIgnoreCase)));

            // Primary type only: default to first image if none found by label
            if (imageStream == null)
            {
                if (type == ImageType.Primary)
                {
                    imageStream = imageStreams[0];
                }
                else
                {
                    // No streams matched, abort
                    return(new DynamicImageResponse {
                        HasImage = false
                    });
                }
            }

            var format = imageStream.Codec switch
            {
                "mjpeg" => ImageFormat.Jpg,
                "png" => ImageFormat.Png,
                "gif" => ImageFormat.Gif,
                _ => ImageFormat.Jpg
            };

            string extractedImagePath =
                await _mediaEncoder.ExtractVideoImage(item.Path, item.Container, mediaSource, imageStream, imageStream.Index, format, cancellationToken)
                .ConfigureAwait(false);

            return(new DynamicImageResponse
            {
                Format = format,
                HasImage = true,
                Path = extractedImagePath,
                Protocol = MediaProtocol.File
            });
        }