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)); }
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)); }
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 }); }
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)); }
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)); }
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 }); }