From fbf8d27637a0b3804cf31665425be372420097a5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 2 Nov 2015 12:25:01 -0500 Subject: update channel db --- MediaBrowser.Model/Entities/MetadataProviders.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'MediaBrowser.Model/Entities') diff --git a/MediaBrowser.Model/Entities/MetadataProviders.cs b/MediaBrowser.Model/Entities/MetadataProviders.cs index 7644b150a..f5ab0c1d4 100644 --- a/MediaBrowser.Model/Entities/MetadataProviders.cs +++ b/MediaBrowser.Model/Entities/MetadataProviders.cs @@ -36,8 +36,6 @@ namespace MediaBrowser.Model.Entities MusicBrainzArtist = 10, MusicBrainzReleaseGroup = 11, Zap2It = 12, - NesBox = 13, - NesBoxRom = 14, TvRage = 15, AudioDbArtist = 16, AudioDbAlbum = 17, -- cgit v1.2.3 From 81bb469fe1ba61d6ff39f6473e5d4beab1764e4e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 9 Nov 2015 13:18:37 -0500 Subject: reduce image processing --- Emby.Drawing/GDI/GDIImageEncoder.cs | 4 +- Emby.Drawing/IImageEncoder.cs | 3 +- Emby.Drawing/ImageMagick/ImageMagickEncoder.cs | 2 +- Emby.Drawing/ImageProcessor.cs | 84 ++++-- Emby.Drawing/NullImageEncoder.cs | 2 +- MediaBrowser.Api/Images/ImageService.cs | 70 +---- MediaBrowser.Controller/Drawing/IImageProcessor.cs | 5 +- .../Drawing/ImageProcessingOptions.cs | 39 ++- MediaBrowser.Controller/Entities/BaseItem.cs | 13 +- .../Entities/UserViewBuilder.cs | 321 +-------------------- MediaBrowser.Model/Entities/CollectionType.cs | 20 -- MediaBrowser.Model/Session/GeneralCommandType.cs | 4 +- .../Manager/ItemImageProvider.cs | 7 +- .../UserViews/DynamicImageProvider.cs | 4 +- 14 files changed, 137 insertions(+), 441 deletions(-) (limited to 'MediaBrowser.Model/Entities') diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing/GDI/GDIImageEncoder.cs index 530613741..11c9eb8e9 100644 --- a/Emby.Drawing/GDI/GDIImageEncoder.cs +++ b/Emby.Drawing/GDI/GDIImageEncoder.cs @@ -89,7 +89,7 @@ namespace Emby.Drawing.GDI } } - public void EncodeImage(string inputPath, string cacheFilePath, int width, int height, int quality, ImageProcessingOptions options) + public void EncodeImage(string inputPath, string cacheFilePath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { var hasPostProcessing = !string.IsNullOrEmpty(options.BackgroundColor) || options.UnplayedCount.HasValue || options.AddPlayedIndicator || options.PercentPlayed > 0; @@ -98,8 +98,6 @@ namespace Emby.Drawing.GDI var newWidth = Convert.ToInt32(width); var newHeight = Convert.ToInt32(height); - var selectedOutputFormat = options.OutputFormat; - // Graphics.FromImage will throw an exception if the PixelFormat is Indexed, so we need to handle that here // Also, Webp only supports Format32bppArgb and Format32bppRgb var pixelFormat = selectedOutputFormat == ImageFormat.Webp diff --git a/Emby.Drawing/IImageEncoder.cs b/Emby.Drawing/IImageEncoder.cs index 4469075a6..bfd382bb7 100644 --- a/Emby.Drawing/IImageEncoder.cs +++ b/Emby.Drawing/IImageEncoder.cs @@ -31,7 +31,8 @@ namespace Emby.Drawing /// The height. /// The quality. /// The options. - void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options); + /// The output format. + void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); /// /// Creates the image collage. diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index d097c8da3..d18ee1caa 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -134,7 +134,7 @@ namespace Emby.Drawing.ImageMagick string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase); } - public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options) + public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { // Even if the caller specified 100, don't use it because it takes forever quality = Math.Min(quality, 99); diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index a24987c05..902ade448 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -19,6 +19,7 @@ using System.Threading.Tasks; using CommonIO; using Emby.Drawing.Common; using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Net; namespace Emby.Drawing { @@ -152,7 +153,7 @@ namespace Emby.Drawing { var file = await ProcessImage(options).ConfigureAwait(false); - using (var fileStream = _fileSystem.GetFileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, true)) + using (var fileStream = _fileSystem.GetFileStream(file.Item1, FileMode.Open, FileAccess.Read, FileShare.Read, true)) { await fileStream.CopyToAsync(toStream).ConfigureAwait(false); } @@ -163,7 +164,7 @@ namespace Emby.Drawing return _imageEncoder.SupportedOutputFormats; } - public async Task ProcessImage(ImageProcessingOptions options) + public async Task> ProcessImage(ImageProcessingOptions options) { if (options == null) { @@ -181,13 +182,7 @@ namespace Emby.Drawing if (!_imageEncoder.SupportsImageEncoding) { - return originalImagePath; - } - - if (options.HasDefaultOptions(originalImagePath) && options.Enhancers.Count == 0 && !options.CropWhiteSpace) - { - // Just spit out the original file if all the options are default - return originalImagePath; + return new Tuple(originalImagePath, MimeTypes.GetMimeType(originalImagePath)); } var dateModified = originalImage.DateModified; @@ -214,19 +209,31 @@ namespace Emby.Drawing dateModified = tuple.Item2; } - var newSizeInfo = GetNewImageSize(originalImagePath, dateModified, options); - var newSize = newSizeInfo.Item1; - var isSizeChanged = newSizeInfo.Item2; + if (options.HasDefaultOptions(originalImagePath)) + { + // Just spit out the original file if all the options are default + return new Tuple(originalImagePath, MimeTypes.GetMimeType(originalImagePath)); + } - if (options.HasDefaultOptionsWithoutSize(originalImagePath) && !isSizeChanged && options.Enhancers.Count == 0) + ImageSize? originalImageSize; + try { - // Just spit out the original file if the new size equals the old - return originalImagePath; + originalImageSize = GetImageSize(originalImagePath, dateModified, true); + if (options.HasDefaultOptions(originalImagePath, originalImageSize.Value)) + { + // Just spit out the original file if all the options are default + return new Tuple(originalImagePath, MimeTypes.GetMimeType(originalImagePath)); + } + } + catch + { + originalImageSize = null; } + var newSize = GetNewImageSize(options, originalImageSize); var quality = options.Quality; - var outputFormat = GetOutputFormat(options.OutputFormat); + var outputFormat = GetOutputFormat(options.SupportedOutputFormats[0]); var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor); var semaphore = GetLock(cacheFilePath); @@ -250,7 +257,7 @@ namespace Emby.Drawing imageProcessingLockTaken = true; - _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, newWidth, newHeight, quality, options); + _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, newWidth, newHeight, quality, options, outputFormat); } } finally @@ -263,27 +270,48 @@ namespace Emby.Drawing semaphore.Release(); } - return cacheFilePath; + return new Tuple(cacheFilePath, GetMimeType(outputFormat, cacheFilePath)); } - private Tuple GetNewImageSize(string originalImagePath, DateTime dateModified, ImageProcessingOptions options) + private string GetMimeType(ImageFormat format, string path) { - try + if (format == ImageFormat.Bmp) + { + return MimeTypes.GetMimeType("i.bmp"); + } + if (format == ImageFormat.Gif) + { + return MimeTypes.GetMimeType("i.gif"); + } + if (format == ImageFormat.Jpg) + { + return MimeTypes.GetMimeType("i.jpg"); + } + if (format == ImageFormat.Png) + { + return MimeTypes.GetMimeType("i.png"); + } + if (format == ImageFormat.Webp) { - var originalImageSize = GetImageSize(originalImagePath, dateModified, true); + return MimeTypes.GetMimeType("i.webp"); + } - // Determine the output size based on incoming parameters - var newSize = DrawingUtils.Resize(originalImageSize, options.Width, options.Height, options.MaxWidth, options.MaxHeight); + return MimeTypes.GetMimeType(path); + } - return new Tuple(newSize, !newSize.Equals(originalImageSize)); - } - catch + private ImageSize GetNewImageSize(ImageProcessingOptions options, ImageSize? originalImageSize) + { + if (originalImageSize.HasValue) { - return new Tuple(GetSizeEstimage(options), true); + // Determine the output size based on incoming parameters + var newSize = DrawingUtils.Resize(originalImageSize.Value, options.Width, options.Height, options.MaxWidth, options.MaxHeight); + + return newSize; } + return GetSizeEstimate(options); } - private ImageSize GetSizeEstimage(ImageProcessingOptions options) + private ImageSize GetSizeEstimate(ImageProcessingOptions options) { if (options.Width.HasValue && options.Height.HasValue) { diff --git a/Emby.Drawing/NullImageEncoder.cs b/Emby.Drawing/NullImageEncoder.cs index 30ea36329..1638a675a 100644 --- a/Emby.Drawing/NullImageEncoder.cs +++ b/Emby.Drawing/NullImageEncoder.cs @@ -32,7 +32,7 @@ namespace Emby.Drawing throw new NotImplementedException(); } - public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options) + public void EncodeImage(string inputPath, string outputPath, int width, int height, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { throw new NotImplementedException(); } diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 8114f9f22..e2354a54b 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -571,8 +571,7 @@ namespace MediaBrowser.Api.Images cropwhitespace = request.CropWhitespace.Value; } - var format = GetOutputFormat(request, imageInfo, cropwhitespace, supportedImageEnhancers); - var contentType = GetMimeType(format, imageInfo.Path); + var outputFormats = GetOutputFormats(request, imageInfo, cropwhitespace, supportedImageEnhancers); var cacheGuid = new Guid(_imageProcessor.GetImageCacheTag(item, imageInfo, supportedImageEnhancers)); @@ -593,9 +592,8 @@ namespace MediaBrowser.Api.Images request, imageInfo, cropwhitespace, - format, + outputFormats, supportedImageEnhancers, - contentType, cacheDuration, responseHeaders, isHeadRequest) @@ -606,9 +604,8 @@ namespace MediaBrowser.Api.Images ImageRequest request, ItemImageInfo image, bool cropwhitespace, - ImageFormat format, + List supportedFormats, List enhancers, - string contentType, TimeSpan? cacheDuration, IDictionary headers, bool isHeadRequest) @@ -629,10 +626,10 @@ namespace MediaBrowser.Api.Images PercentPlayed = request.PercentPlayed ?? 0, UnplayedCount = request.UnplayedCount, BackgroundColor = request.BackgroundColor, - OutputFormat = format + SupportedOutputFormats = supportedFormats }; - var file = await _imageProcessor.ProcessImage(options).ConfigureAwait(false); + var imageResult = await _imageProcessor.ProcessImage(options).ConfigureAwait(false); headers["Vary"] = "Accept"; @@ -640,20 +637,20 @@ namespace MediaBrowser.Api.Images { CacheDuration = cacheDuration, ResponseHeaders = headers, - ContentType = contentType, + ContentType = imageResult.Item2, IsHeadRequest = isHeadRequest, - Path = file + Path = imageResult.Item1 }); } - private ImageFormat GetOutputFormat(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List enhancers) + private List GetOutputFormats(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List enhancers) { if (!string.IsNullOrWhiteSpace(request.Format)) { ImageFormat format; if (Enum.TryParse(request.Format, true, out format)) { - return format; + return new List { format }; } } @@ -671,39 +668,30 @@ namespace MediaBrowser.Api.Images } var clientSupportedFormats = GetClientSupportedFormats(); - if (inputFormat.HasValue && clientSupportedFormats.Contains(inputFormat.Value) && enhancers.Count == 0) - { - if ((request.Quality ?? 100) == 100 && !request.Height.HasValue && !request.Width.HasValue && - !request.AddPlayedIndicator && !request.PercentPlayed.HasValue && !request.UnplayedCount.HasValue && string.IsNullOrWhiteSpace(request.BackgroundColor)) - { - // TODO: Allow this when specfying max width/height if the value is in range - if (!cropwhitespace && !request.MaxHeight.HasValue && !request.MaxWidth.HasValue) - { - return inputFormat.Value; - } - } - } var serverFormats = _imageProcessor.GetSupportedImageOutputFormats(); + var outputFormats = new List(); // Client doesn't care about format, so start with webp if supported if (serverFormats.Contains(ImageFormat.Webp) && clientSupportedFormats.Contains(ImageFormat.Webp)) { - return ImageFormat.Webp; + outputFormats.Add(ImageFormat.Webp); } if (enhancers.Count > 0) { - return ImageFormat.Png; + outputFormats.Add(ImageFormat.Png); } if (inputFormat.HasValue && inputFormat.Value == ImageFormat.Jpg) { - return ImageFormat.Jpg; + outputFormats.Add(ImageFormat.Jpg); } // We can't predict if there will be transparency or not, so play it safe - return ImageFormat.Png; + outputFormats.Add(ImageFormat.Png); + + return outputFormats; } private ImageFormat[] GetClientSupportedFormats() @@ -730,32 +718,6 @@ namespace MediaBrowser.Api.Images return new[] { ImageFormat.Jpg, ImageFormat.Png }; } - private string GetMimeType(ImageFormat format, string path) - { - if (format == ImageFormat.Bmp) - { - return MimeTypes.GetMimeType("i.bmp"); - } - if (format == ImageFormat.Gif) - { - return MimeTypes.GetMimeType("i.gif"); - } - if (format == ImageFormat.Jpg) - { - return MimeTypes.GetMimeType("i.jpg"); - } - if (format == ImageFormat.Png) - { - return MimeTypes.GetMimeType("i.png"); - } - if (format == ImageFormat.Webp) - { - return MimeTypes.GetMimeType("i.webp"); - } - - return MimeTypes.GetMimeType(path); - } - /// /// Gets the image path. /// diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index e1e98857f..058bf70cd 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Entities; +using System; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; @@ -83,7 +84,7 @@ namespace MediaBrowser.Controller.Drawing /// /// The options. /// Task. - Task ProcessImage(ImageProcessingOptions options); + Task> ProcessImage(ImageProcessingOptions options); /// /// Gets the enhanced image. diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs index e6bf86853..2b80b701e 100644 --- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs +++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs @@ -4,6 +4,7 @@ using MediaBrowser.Model.Drawing; using System; using System.Collections.Generic; using System.IO; +using System.Linq; namespace MediaBrowser.Controller.Drawing { @@ -29,7 +30,7 @@ namespace MediaBrowser.Controller.Drawing public List Enhancers { get; set; } - public ImageFormat OutputFormat { get; set; } + public List SupportedOutputFormats { get; set; } public bool AddPlayedIndicator { get; set; } @@ -48,19 +49,47 @@ namespace MediaBrowser.Controller.Drawing !MaxHeight.HasValue; } + public bool HasDefaultOptions(string originalImagePath, ImageSize size) + { + if (!HasDefaultOptionsWithoutSize(originalImagePath)) + { + return false; + } + + if (Width.HasValue && !size.Width.Equals(Width.Value)) + { + return false; + } + if (Height.HasValue && !size.Height.Equals(Height.Value)) + { + return false; + } + if (MaxWidth.HasValue && size.Width > MaxWidth.Value) + { + return false; + } + if (MaxHeight.HasValue && size.Height > MaxHeight.Value) + { + return false; + } + + return true; + } + public bool HasDefaultOptionsWithoutSize(string originalImagePath) { - return (Quality == 100) && - IsOutputFormatDefault(originalImagePath) && + return (Quality >= 90) && + IsFormatSupported(originalImagePath) && !AddPlayedIndicator && PercentPlayed.Equals(0) && !UnplayedCount.HasValue && string.IsNullOrEmpty(BackgroundColor); } - private bool IsOutputFormatDefault(string originalImagePath) + private bool IsFormatSupported(string originalImagePath) { - return string.Equals(Path.GetExtension(originalImagePath), "." + OutputFormat, StringComparison.OrdinalIgnoreCase); + var ext = Path.GetExtension(originalImagePath); + return SupportedOutputFormats.Any(outputFormat => string.Equals(ext, "." + outputFormat, StringComparison.OrdinalIgnoreCase)); } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 5b0af42e8..d9b7b1ae7 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -690,9 +690,10 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public int? ParentIndexNumber { get; set; } - public virtual string GetOfficialRatingForComparison(bool inherit) + [IgnoreDataMember] + public string OfficialRatingForComparison { - if (inherit) + get { if (!string.IsNullOrWhiteSpace(OfficialRating)) { @@ -702,13 +703,11 @@ namespace MediaBrowser.Controller.Entities var parent = DisplayParent; if (parent != null) { - return parent.GetOfficialRatingForComparison(inherit); + return parent.OfficialRatingForComparison; } return null; } - - return OfficialRating; } [IgnoreDataMember] @@ -1141,7 +1140,7 @@ namespace MediaBrowser.Controller.Entities if (string.IsNullOrWhiteSpace(rating)) { - rating = GetOfficialRatingForComparison(true); + rating = OfficialRatingForComparison; } if (string.IsNullOrWhiteSpace(rating)) @@ -1190,7 +1189,7 @@ namespace MediaBrowser.Controller.Entities if (string.IsNullOrWhiteSpace(rating)) { - rating = GetOfficialRatingForComparison(true); + rating = OfficialRatingForComparison; } if (string.IsNullOrWhiteSpace(rating)) diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 4d5f14f8c..87f45ec8e 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -125,7 +125,14 @@ namespace MediaBrowser.Controller.Entities case CollectionType.HomeVideos: case CollectionType.Games: case CollectionType.MusicVideos: + case CollectionType.Music: + { + if (query.Recursive) + { + return GetResult(queryParent.GetRecursiveChildren(user, true), queryParent, query); + } return GetResult(queryParent.GetChildren(user, true), queryParent, query); + } case CollectionType.Folders: return GetResult(user.RootFolder.GetChildren(user, true), queryParent, query); @@ -139,36 +146,9 @@ namespace MediaBrowser.Controller.Entities case CollectionType.TvShows: return await GetTvView(queryParent, user, query).ConfigureAwait(false); - case CollectionType.Music: - return await GetMusicFolders(queryParent, user, query).ConfigureAwait(false); - case CollectionType.Movies: return await GetMovieFolders(queryParent, user, query).ConfigureAwait(false); - case SpecialFolder.MusicGenres: - return await GetMusicGenres(queryParent, user, query).ConfigureAwait(false); - - case SpecialFolder.MusicGenre: - return await GetMusicGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false); - - case SpecialFolder.GameGenres: - return await GetGameGenres(queryParent, user, query).ConfigureAwait(false); - - case SpecialFolder.GameGenre: - return await GetGameGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false); - - case SpecialFolder.GameSystems: - return GetGameSystems(queryParent, user, query); - - case SpecialFolder.LatestGames: - return GetLatestGames(queryParent, user, query); - - case SpecialFolder.RecentlyPlayedGames: - return GetRecentlyPlayedGames(queryParent, user, query); - - case SpecialFolder.GameFavorites: - return GetFavoriteGames(queryParent, user, query); - case SpecialFolder.TvShowSeries: return GetTvSeries(queryParent, user, query); @@ -208,42 +188,12 @@ namespace MediaBrowser.Controller.Entities case SpecialFolder.MovieCollections: return GetMovieCollections(queryParent, user, query); - case SpecialFolder.MusicLatest: - return GetMusicLatest(queryParent, user, query); - - case SpecialFolder.MusicPlaylists: - return await GetMusicPlaylists(queryParent, user, query).ConfigureAwait(false); - - case SpecialFolder.MusicAlbums: - return GetMusicAlbums(queryParent, user, query); - - case SpecialFolder.MusicAlbumArtists: - return GetMusicAlbumArtists(queryParent, user, query); - - case SpecialFolder.MusicArtists: - return GetMusicArtists(queryParent, user, query); - - case SpecialFolder.MusicSongs: - return GetMusicSongs(queryParent, user, query); - case SpecialFolder.TvFavoriteEpisodes: return GetFavoriteEpisodes(queryParent, user, query); case SpecialFolder.TvFavoriteSeries: return GetFavoriteSeries(queryParent, user, query); - case SpecialFolder.MusicFavorites: - return await GetMusicFavorites(queryParent, user, query).ConfigureAwait(false); - - case SpecialFolder.MusicFavoriteAlbums: - return GetFavoriteAlbums(queryParent, user, query); - - case SpecialFolder.MusicFavoriteArtists: - return GetFavoriteArtists(queryParent, user, query); - - case SpecialFolder.MusicFavoriteSongs: - return GetFavoriteSongs(queryParent, user, query); - default: { if (queryParent is UserView) @@ -270,154 +220,6 @@ namespace MediaBrowser.Controller.Entities return 50; } - private async Task> GetMusicFolders(Folder parent, User user, InternalItemsQuery query) - { - if (query.Recursive) - { - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => FilterItem(i, query)); - - return PostFilterAndSort(items, parent, null, query); - } - - var list = new List(); - - list.Add(await GetUserView(SpecialFolder.MusicLatest, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicPlaylists, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicAlbums, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, "3", parent).ConfigureAwait(false)); - //list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "4", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicSongs, "5", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicGenres, "6", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicFavorites, "7", parent).ConfigureAwait(false)); - - return GetResult(list, parent, query); - } - - private async Task> GetMusicFavorites(Folder parent, User user, InternalItemsQuery query) - { - var list = new List(); - - list.Add(await GetUserView(SpecialFolder.MusicFavoriteAlbums, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicFavoriteArtists, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicFavoriteSongs, "2", parent).ConfigureAwait(false)); - - return GetResult(list, parent, query); - } - - private async Task> GetMusicGenres(Folder parent, User user, InternalItemsQuery query) - { - var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) - .Where(i => !i.IsFolder) - .SelectMany(i => i.Genres) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetMusicGenre(i); - } - catch - { - // Full exception logged at lower levels - _logger.Error("Error getting genre"); - return null; - } - - }) - .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.MusicGenre, i.SortName, parent)); - - var genres = await Task.WhenAll(tasks).ConfigureAwait(false); - - return GetResult(genres, parent, query); - } - - private async Task> GetMusicGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query) - { - var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) - .Where(i => !i.IsFolder) - .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase)) - .OfType(); - - var artists = _libraryManager.GetAlbumArtists(items); - - return GetResult(artists, queryParent, query); - } - - private QueryResult GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query) - { - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) - .Where(i => !i.IsFolder) - .OfType(); - - var artists = _libraryManager.GetAlbumArtists(items); - - return GetResult(artists, parent, query); - } - - private QueryResult GetMusicArtists(Folder parent, User user, InternalItemsQuery query) - { - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) - .Where(i => !i.IsFolder) - .OfType(); - - var artists = _libraryManager.GetArtists(items); - - return GetResult(artists, parent, query); - } - - private QueryResult GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query) - { - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) - .Where(i => !i.IsFolder) - .OfType(); - - var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite); - - return GetResult(artists, parent, query); - } - - private Task> GetMusicPlaylists(Folder parent, User user, InternalItemsQuery query) - { - query.IncludeItemTypes = new[] { "Playlist" }; - query.Recursive = true; - - return parent.GetItems(query); - } - - private QueryResult GetMusicAlbums(Folder parent, User user, InternalItemsQuery query) - { - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => (i is MusicAlbum) && FilterItem(i, query)); - - return PostFilterAndSort(items, parent, null, query); - } - - private QueryResult GetMusicSongs(Folder parent, User user, InternalItemsQuery query) - { - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => (i is Audio.Audio) && FilterItem(i, query)); - - return PostFilterAndSort(items, parent, null, query); - } - - private QueryResult GetMusicLatest(Folder parent, User user, InternalItemsQuery query) - { - var items = _userViewManager.GetLatestItems(new LatestItemsQuery - { - UserId = user.Id.ToString("N"), - Limit = GetSpecialItemsLimit(), - IncludeItemTypes = new[] { typeof(Audio.Audio).Name }, - ParentId = (parent == null ? null : parent.Id.ToString("N")), - GroupItems = true - - }).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null); - - query.SortBy = new string[] { }; - - //var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => i is MusicVideo || i is Audio.Audio && FilterItem(i, query)); - - return PostFilterAndSort(items, parent, null, query); - } - private async Task> GetMovieFolders(Folder parent, User user, InternalItemsQuery query) { if (query.Recursive) @@ -476,24 +278,6 @@ namespace MediaBrowser.Controller.Entities return PostFilterAndSort(items, parent, null, query); } - private QueryResult GetFavoriteSongs(Folder parent, User user, InternalItemsQuery query) - { - query.IsFavorite = true; - - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music }, i => (i is Audio.Audio) && FilterItem(i, query)); - - return PostFilterAndSort(items, parent, null, query); - } - - private QueryResult GetFavoriteAlbums(Folder parent, User user, InternalItemsQuery query) - { - query.IsFavorite = true; - - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music }, i => (i is MusicAlbum) && FilterItem(i, query)); - - return PostFilterAndSort(items, parent, null, query); - } - private QueryResult GetMovieMovies(Folder parent, User user, InternalItemsQuery query) { var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }, i => (i is Movie) && FilterItem(i, query)); @@ -613,54 +397,6 @@ namespace MediaBrowser.Controller.Entities return GetResult(list, parent, query); } - private async Task> GetGameView(User user, Folder parent, InternalItemsQuery query) - { - if (query.Recursive) - { - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => FilterItem(i, query)); - return PostFilterAndSort(items, parent, null, query); - } - - var list = new List(); - - list.Add(await GetUserView(SpecialFolder.LatestGames, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.RecentlyPlayedGames, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.GameFavorites, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.GameSystems, "3", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.GameGenres, "4", parent).ConfigureAwait(false)); - - return GetResult(list, parent, query); - } - - private QueryResult GetLatestGames(Folder parent, User user, InternalItemsQuery query) - { - query.SortBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName }; - query.SortOrder = SortOrder.Descending; - - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => i is Game && FilterItem(i, query)); - - return PostFilterAndSort(items, parent, GetSpecialItemsLimit(), query); - } - - private QueryResult GetRecentlyPlayedGames(Folder parent, User user, InternalItemsQuery query) - { - query.IsPlayed = true; - query.SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName }; - query.SortOrder = SortOrder.Descending; - - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => i is Game && FilterItem(i, query)); - - return PostFilterAndSort(items, parent, GetSpecialItemsLimit(), query); - } - - private QueryResult GetFavoriteGames(Folder parent, User user, InternalItemsQuery query) - { - query.IsFavorite = true; - - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => i is Game && FilterItem(i, query)); - return PostFilterAndSort(items, parent, null, query); - } - private QueryResult GetTvLatest(Folder parent, User user, InternalItemsQuery query) { query.SortBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName }; @@ -741,49 +477,6 @@ namespace MediaBrowser.Controller.Entities return GetResult(items, queryParent, query); } - private QueryResult GetGameSystems(Folder parent, User user, InternalItemsQuery query) - { - var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => i is GameSystem && FilterItem(i, query)); - - return PostFilterAndSort(items, parent, null, query); - } - - private async Task> GetGameGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query) - { - var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Games }, - i => i is Game && i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase)); - - return GetResult(items, queryParent, query); - } - - private async Task> GetGameGenres(Folder parent, User user, InternalItemsQuery query) - { - var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }) - .OfType() - .SelectMany(i => i.Genres) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetGameGenre(i); - } - catch - { - // Full exception logged at lower levels - _logger.Error("Error getting game genre"); - return null; - } - - }) - .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.GameGenre, i.SortName, parent)); - - var genres = await Task.WhenAll(tasks).ConfigureAwait(false); - - return GetResult(genres, parent, query); - } - private QueryResult GetResult(QueryResult result) where T : BaseItem { diff --git a/MediaBrowser.Model/Entities/CollectionType.cs b/MediaBrowser.Model/Entities/CollectionType.cs index a259f4c07..dfd8f309c 100644 --- a/MediaBrowser.Model/Entities/CollectionType.cs +++ b/MediaBrowser.Model/Entities/CollectionType.cs @@ -47,25 +47,5 @@ public const string MovieFavorites = "MovieFavorites"; public const string MovieGenres = "MovieGenres"; public const string MovieGenre = "MovieGenre"; - - public const string LatestGames = "LatestGames"; - public const string RecentlyPlayedGames = "RecentlyPlayedGames"; - public const string GameSystems = "GameSystems"; - public const string GameGenres = "GameGenres"; - public const string GameFavorites = "GameFavorites"; - public const string GameGenre = "GameGenre"; - - public const string MusicArtists = "MusicArtists"; - public const string MusicAlbumArtists = "MusicAlbumArtists"; - public const string MusicAlbums = "MusicAlbums"; - public const string MusicGenres = "MusicGenres"; - public const string MusicGenre = "MusicGenre"; - public const string MusicLatest = "MusicLatest"; - public const string MusicPlaylists = "MusicPlaylists"; - public const string MusicSongs = "MusicSongs"; - public const string MusicFavorites = "MusicFavorites"; - public const string MusicFavoriteArtists = "MusicFavoriteArtists"; - public const string MusicFavoriteAlbums = "MusicFavoriteAlbums"; - public const string MusicFavoriteSongs = "MusicFavoriteSongs"; } } diff --git a/MediaBrowser.Model/Session/GeneralCommandType.cs b/MediaBrowser.Model/Session/GeneralCommandType.cs index 79220f066..64b61678e 100644 --- a/MediaBrowser.Model/Session/GeneralCommandType.cs +++ b/MediaBrowser.Model/Session/GeneralCommandType.cs @@ -34,6 +34,8 @@ DisplayContent = 26, GoToSearch = 27, DisplayMessage = 28, - SetRepeatMode = 29 + SetRepeatMode = 29, + ChannelUp = 30, + ChannelDown = 31 } } \ No newline at end of file diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index 0533e6ca0..fcb208a05 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -527,6 +527,11 @@ namespace MediaBrowser.Providers.Manager { var newIndex = item.AllowsMultipleImages(imageType) ? item.GetImages(imageType).Count() : 0; + SaveImageStub(item, imageType, url, newIndex); + } + + private void SaveImageStub(IHasImages item, ImageType imageType, string url, int newIndex) + { item.SetImage(new ItemImageInfo { Path = url, @@ -555,7 +560,7 @@ namespace MediaBrowser.Providers.Manager { SaveImageStub(item, imageType, url); result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; - return; + continue; } try diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index cdffadcd7..167b5706e 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -54,9 +54,7 @@ namespace MediaBrowser.Server.Implementations.UserViews return new List(); } - if (string.Equals(view.ViewType, SpecialFolder.GameGenre, StringComparison.OrdinalIgnoreCase) || - string.Equals(view.ViewType, SpecialFolder.MusicGenre, StringComparison.OrdinalIgnoreCase) || - string.Equals(view.ViewType, SpecialFolder.MovieGenre, StringComparison.OrdinalIgnoreCase) || + if (string.Equals(view.ViewType, SpecialFolder.MovieGenre, StringComparison.OrdinalIgnoreCase) || string.Equals(view.ViewType, SpecialFolder.TvGenre, StringComparison.OrdinalIgnoreCase)) { var userItemsResult = await view.GetItems(new InternalItemsQuery -- cgit v1.2.3 From 35449735be8384ff6d37820afbe03c59efdf2fee Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 17 Nov 2015 12:35:43 -0500 Subject: add back CollectionType --- MediaBrowser.Model/Entities/CollectionType.cs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Model/Entities') diff --git a/MediaBrowser.Model/Entities/CollectionType.cs b/MediaBrowser.Model/Entities/CollectionType.cs index dfd8f309c..187334c71 100644 --- a/MediaBrowser.Model/Entities/CollectionType.cs +++ b/MediaBrowser.Model/Entities/CollectionType.cs @@ -47,5 +47,25 @@ public const string MovieFavorites = "MovieFavorites"; public const string MovieGenres = "MovieGenres"; public const string MovieGenre = "MovieGenre"; + + public const string LatestGames = "LatestGames"; + public const string RecentlyPlayedGames = "RecentlyPlayedGames"; + public const string GameSystems = "GameSystems"; + public const string GameGenres = "GameGenres"; + public const string GameFavorites = "GameFavorites"; + public const string GameGenre = "GameGenre"; + + public const string MusicArtists = "MusicArtists"; + public const string MusicAlbumArtists = "MusicAlbumArtists"; + public const string MusicAlbums = "MusicAlbums"; + public const string MusicGenres = "MusicGenres"; + public const string MusicGenre = "MusicGenre"; + public const string MusicLatest = "MusicLatest"; + public const string MusicPlaylists = "MusicPlaylists"; + public const string MusicSongs = "MusicSongs"; + public const string MusicFavorites = "MusicFavorites"; + public const string MusicFavoriteArtists = "MusicFavoriteArtists"; + public const string MusicFavoriteAlbums = "MusicFavoriteAlbums"; + public const string MusicFavoriteSongs = "MusicFavoriteSongs"; } -} +} \ No newline at end of file -- cgit v1.2.3 From 02938e7bcb0459a44dfa6c9e7dfa2a04be3467be Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 12 Dec 2015 01:49:03 -0500 Subject: update keyframe setting --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 + MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 42 +----- .../Playback/Progressive/VideoService.cs | 1 + .../MediaEncoding/MediaInfoRequest.cs | 1 - MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 157 +-------------------- .../Configuration/ServerConfiguration.cs | 2 - MediaBrowser.Model/Entities/MediaStream.cs | 3 - .../MediaInfo/FFProbeVideoInfo.cs | 3 +- .../Persistence/SqliteItemRepository.cs | 23 +-- MediaBrowser.WebDashboard/Api/DashboardService.cs | 5 + 10 files changed, 15 insertions(+), 224 deletions(-) (limited to 'MediaBrowser.Model/Entities') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index a940be763..eacd7999c 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -2178,6 +2178,8 @@ namespace MediaBrowser.Api.Playback inputModifier += " " + videoDecoder; } + //inputModifier += " -noaccurate_seek"; + return inputModifier; } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 3724c8868..c6abffd07 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -291,25 +291,6 @@ namespace MediaBrowser.Api.Playback.Hls private double[] GetSegmentLengths(StreamState state) { var result = new List(); - if (state.VideoRequest != null) - { - var encoder = GetVideoEncoder(state); - - if (string.Equals(encoder, "copy", StringComparison.OrdinalIgnoreCase)) - { - var videoStream = state.VideoStream; - if (videoStream.KeyFrames != null && videoStream.KeyFrames.Count > 0) - { - foreach (var frame in videoStream.KeyFrames) - { - var seconds = TimeSpan.FromMilliseconds(frame).TotalSeconds; - seconds -= result.Sum(); - result.Add(seconds); - } - return result.ToArray(); - } - } - } var ticks = state.RunTimeTicks ?? 0; @@ -936,27 +917,8 @@ namespace MediaBrowser.Api.Playback.Hls protected override bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) { - if (videoStream.KeyFrames == null || videoStream.KeyFrames.Count == 0) - { - Logger.Debug("Cannot stream copy video due to missing keyframe info"); - return false; - } - - var previousSegment = 0; - foreach (var frame in videoStream.KeyFrames) - { - var length = frame - previousSegment; - - // Don't allow really long segments because this could result in long download times - if (length > 10000) - { - Logger.Debug("Cannot stream copy video due to long segment length of {0}ms", length); - return false; - } - previousSegment = frame; - } - - return base.CanStreamCopyVideo(request, videoStream); + return false; + //return base.CanStreamCopyVideo(request, videoStream); } } } \ No newline at end of file diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index d79040dd4..519bfa8d8 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -100,6 +100,7 @@ namespace MediaBrowser.Api.Playback.Progressive { // Comparison: https://github.com/jansmolders86/mediacenterjs/blob/master/lib/transcoding/desktop.js format = " -f mp4 -movflags frag_keyframe+empty_moov"; + //format = " -avoid_negative_ts disabled -start_at_zero -copyts -f mp4 -movflags frag_keyframe+empty_moov"; } var threads = GetNumberOfThreads(state, string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase)); diff --git a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs index 24df7b885..ca0c2fdbb 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs @@ -15,7 +15,6 @@ namespace MediaBrowser.Controller.MediaEncoding public IIsoMount MountedIso { get; set; } public VideoType VideoType { get; set; } public List PlayableStreamFileNames { get; set; } - public bool ExtractKeyFrameInterval { get; set; } public MediaInfoRequest() { diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index c8361ea04..a61b15ac5 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -135,9 +135,7 @@ namespace MediaBrowser.MediaEncoding.Encoder var inputFiles = MediaEncoderHelpers.GetInputArgument(FileSystem, request.InputPath, request.Protocol, request.MountedIso, request.PlayableStreamFileNames); - var extractKeyFrameInterval = request.ExtractKeyFrameInterval && request.Protocol == MediaProtocol.File && request.VideoType == VideoType.VideoFile; - - return GetMediaInfoInternal(GetInputArgument(inputFiles, request.Protocol), request.InputPath, request.Protocol, extractChapters, extractKeyFrameInterval, + return GetMediaInfoInternal(GetInputArgument(inputFiles, request.Protocol), request.InputPath, request.Protocol, extractChapters, GetProbeSizeArgument(inputFiles, request.Protocol), request.MediaType == DlnaProfileType.Audio, request.VideoType, cancellationToken); } @@ -171,18 +169,16 @@ namespace MediaBrowser.MediaEncoding.Encoder /// The primary path. /// The protocol. /// if set to true [extract chapters]. - /// if set to true [extract key frame interval]. /// The probe size argument. /// if set to true [is audio]. /// Type of the video. /// The cancellation token. /// Task{MediaInfoResult}. - /// + /// ffprobe failed - streams and format are both null. private async Task GetMediaInfoInternal(string inputPath, string primaryPath, MediaProtocol protocol, bool extractChapters, - bool extractKeyFrameInterval, string probeSizeArgument, bool isAudio, VideoType videoType, @@ -262,31 +258,6 @@ namespace MediaBrowser.MediaEncoding.Encoder var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); - if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue) - { - if (ConfigurationManager.Configuration.EnableVideoFrameByFrameAnalysis && mediaInfo.Size.HasValue) - { - foreach (var stream in mediaInfo.MediaStreams) - { - if (EnableKeyframeExtraction(mediaInfo, stream)) - { - try - { - stream.KeyFrames = await GetKeyFrames(inputPath, stream.Index, cancellationToken).ConfigureAwait(false); - } - catch (OperationCanceledException) - { - - } - catch (Exception ex) - { - _logger.ErrorException("Error getting key frame interval", ex); - } - } - } - } - } - return mediaInfo; } catch @@ -300,132 +271,8 @@ namespace MediaBrowser.MediaEncoding.Encoder _ffProbeResourcePool.Release(); } } - - throw new ApplicationException(string.Format("FFProbe failed for {0}", inputPath)); - } - - private bool EnableKeyframeExtraction(MediaSourceInfo mediaSource, MediaStream videoStream) - { - if (videoStream.Type == MediaStreamType.Video && string.Equals(videoStream.Codec, "h264", StringComparison.OrdinalIgnoreCase) && - !videoStream.IsInterlaced && - !(videoStream.IsAnamorphic ?? false)) - { - var audioStreams = mediaSource.MediaStreams.Where(i => i.Type == MediaStreamType.Audio).ToList(); - - // If it has aac audio then it will probably direct stream anyway, so don't bother with this - if (audioStreams.Count == 1 && string.Equals(audioStreams[0].Codec, "aac", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - return true; - } - return false; - } - - private async Task> GetKeyFrames(string inputPath, int videoStreamIndex, CancellationToken cancellationToken) - { - inputPath = inputPath.Split(new[] { ':' }, 2).Last().Trim('"'); - - const string args = "-show_packets -print_format compact -select_streams v:{1} -show_entries packet=flags -show_entries packet=pts_time \"{0}\""; - - var process = new Process - { - StartInfo = new ProcessStartInfo - { - CreateNoWindow = true, - UseShellExecute = false, - - // Must consume both or ffmpeg may hang due to deadlocks. See comments below. - RedirectStandardOutput = true, - RedirectStandardError = true, - FileName = FFProbePath, - Arguments = string.Format(args, inputPath, videoStreamIndex.ToString(CultureInfo.InvariantCulture)).Trim(), - - WindowStyle = ProcessWindowStyle.Hidden, - ErrorDialog = false - }, - - EnableRaisingEvents = true - }; - - _logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); - - using (process) - { - var start = DateTime.UtcNow; - - process.Start(); - - var lines = new List(); - - try - { - process.BeginErrorReadLine(); - - await StartReadingOutput(process.StandardOutput.BaseStream, lines, cancellationToken).ConfigureAwait(false); - } - catch (OperationCanceledException) - { - if (cancellationToken.IsCancellationRequested) - { - throw; - } - } - - process.WaitForExit(); - - _logger.Info("Keyframe extraction took {0} seconds", (DateTime.UtcNow - start).TotalSeconds); - //_logger.Debug("Found keyframes {0}", string.Join(",", lines.ToArray())); - return lines; - } } - private async Task StartReadingOutput(Stream source, List keyframes, CancellationToken cancellationToken) - { - try - { - using (var reader = new StreamReader(source)) - { - var text = await reader.ReadToEndAsync().ConfigureAwait(false); - - var lines = StringHelper.RegexSplit(text, "[\r\n]+"); - foreach (var line in lines) - { - if (string.IsNullOrWhiteSpace(line)) - { - continue; - } - - var values = line.Split('|') - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Select(i => i.Split('=')) - .Where(i => i.Length == 2) - .ToDictionary(i => i[0], i => i[1]); - - string flags; - if (values.TryGetValue("flags", out flags) && string.Equals(flags, "k", StringComparison.OrdinalIgnoreCase)) - { - string pts_time; - double frameSeconds; - if (values.TryGetValue("pts_time", out pts_time) && double.TryParse(pts_time, NumberStyles.Any, CultureInfo.InvariantCulture, out frameSeconds)) - { - var ms = frameSeconds * 1000; - keyframes.Add(Convert.ToInt32(ms)); - } - } - } - } - } - catch (OperationCanceledException) - { - throw; - } - catch (Exception ex) - { - _logger.ErrorException("Error reading ffprobe output", ex); - } - } /// /// The us culture /// diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 5666a32be..08f7f89e3 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -209,8 +209,6 @@ namespace MediaBrowser.Model.Configuration public bool EnableWindowsShortcuts { get; set; } - public bool EnableVideoFrameByFrameAnalysis { get; set; } - public bool EnableDateLastRefresh { get; set; } public string[] Migrations { get; set; } diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 79d1df911..d089f0aa9 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -233,8 +233,5 @@ namespace MediaBrowser.Model.Entities /// /// null if [is cabac] contains no value, true if [is cabac]; otherwise, false. public bool? IsCabac { get; set; } - - [IgnoreDataMember] - public List KeyFrames { get; set; } } } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 5a87e7628..4744b3729 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -170,8 +170,7 @@ namespace MediaBrowser.Providers.MediaInfo VideoType = item.VideoType, MediaType = DlnaProfileType.Video, InputPath = item.Path, - Protocol = protocol, - ExtractKeyFrameInterval = true + Protocol = protocol }, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 6b834bbf2..1d3ac293e 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -127,7 +127,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); var createMediaStreamsTableCommand - = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, IsCabac BIT NULL, KeyFrames TEXT NULL, CodecTag TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; + = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, IsCabac BIT NULL, CodecTag TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; string[] queries = { @@ -385,7 +385,6 @@ namespace MediaBrowser.Server.Implementations.Persistence "IsAnamorphic", "RefFrames", "IsCabac", - "KeyFrames", "CodecTag" }; @@ -2683,15 +2682,6 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveStreamCommand.GetParameter(index++).Value = stream.RefFrames; _saveStreamCommand.GetParameter(index++).Value = stream.IsCabac; - if (stream.KeyFrames == null || stream.KeyFrames.Count == 0) - { - _saveStreamCommand.GetParameter(index++).Value = null; - } - else - { - _saveStreamCommand.GetParameter(index++).Value = string.Join(",", stream.KeyFrames.Select(i => i.ToString(CultureInfo.InvariantCulture)).ToArray()); - } - _saveStreamCommand.GetParameter(index++).Value = stream.CodecTag; _saveStreamCommand.Transaction = transaction; @@ -2848,16 +2838,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!reader.IsDBNull(26)) { - var frames = reader.GetString(26); - if (!string.IsNullOrWhiteSpace(frames)) - { - item.KeyFrames = frames.Split(',').Select(i => int.Parse(i, CultureInfo.InvariantCulture)).ToList(); - } - } - - if (!reader.IsDBNull(27)) - { - item.CodecTag = reader.GetString(27); + item.CodecTag = reader.GetString(26); } return item; diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index d24a4a3de..c16c63578 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -303,6 +303,11 @@ namespace MediaBrowser.WebDashboard.Api var mode = request.Mode; + if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) + { + _fileSystem.DeleteFile(Path.Combine(path, "scripts", "registrationservices.js")); + } + // Try to trim the output size a bit var bowerPath = Path.Combine(path, "bower_components"); DeleteFilesByExtension(bowerPath, ".log"); -- cgit v1.2.3 From 821e8246872cfa380249bca2f79ea810f27c87d5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 2 Jan 2016 16:54:37 -0500 Subject: better caching of remote data --- MediaBrowser.Api/System/SystemService.cs | 13 -- .../Security/PluginSecurityManager.cs | 60 --------- .../Updates/InstallationManager.cs | 103 ++++++++++---- MediaBrowser.Common/Security/ISecurityManager.cs | 6 - .../MediaBrowser.Model.Portable.csproj | 3 - .../MediaBrowser.Model.net35.csproj | 3 - MediaBrowser.Model/Entities/SupporterInfo.cs | 15 --- MediaBrowser.Model/MediaBrowser.Model.csproj | 1 - .../Connect/ConnectEntryPoint.cs | 3 +- .../Connect/ConnectManager.cs | 15 --- .../EntryPoints/LoadRegistrations.cs | 2 +- .../Notifications/RemoteNotifications.cs | 148 --------------------- .../MediaBrowser.Server.Implementations.csproj | 1 - 13 files changed, 79 insertions(+), 294 deletions(-) delete mode 100644 MediaBrowser.Model/Entities/SupporterInfo.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs (limited to 'MediaBrowser.Model/Entities') diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index 539b920a7..9b6b6a7d6 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -78,12 +78,6 @@ namespace MediaBrowser.Api.System public string Name { get; set; } } - [Route("/System/SupporterInfo", "GET")] - [Authenticated] - public class GetSupporterInfo : IReturn - { - } - /// /// Class SystemInfoService /// @@ -116,13 +110,6 @@ namespace MediaBrowser.Api.System _security = security; } - public async Task Get(GetSupporterInfo request) - { - var result = await _security.GetSupporterInfo().ConfigureAwait(false); - - return ToOptimizedResult(result); - } - public object Post(PingSystem request) { return _appHost.Name; diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index e796dba76..d8f350207 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -153,66 +153,6 @@ namespace MediaBrowser.Common.Implementations.Security } } - public async Task GetSupporterInfo() - { - var key = SupporterKey; - - if (string.IsNullOrWhiteSpace(key)) - { - return new SupporterInfo(); - } - - var data = new Dictionary - { - { "key", key }, - }; - - var url = MbAdmin.HttpsUrl + "/service/supporter/retrieve"; - - using (var stream = await _httpClient.Post(url, data, CancellationToken.None).ConfigureAwait(false)) - { - var response = _jsonSerializer.DeserializeFromStream(stream); - - var info = new SupporterInfo - { - Email = response.email, - PlanType = response.planType, - SupporterKey = response.supporterKey, - IsActiveSupporter = IsMBSupporter - }; - - if (!string.IsNullOrWhiteSpace(response.expDate)) - { - DateTime parsedDate; - if (DateTime.TryParse(response.expDate, out parsedDate)) - { - info.ExpirationDate = parsedDate; - } - else - { - _logger.Error("Failed to parse expDate: {0}", response.expDate); - } - } - - if (!string.IsNullOrWhiteSpace(response.regDate)) - { - DateTime parsedDate; - if (DateTime.TryParse(response.regDate, out parsedDate)) - { - info.RegistrationDate = parsedDate; - } - else - { - _logger.Error("Failed to parse regDate: {0}", response.regDate); - } - } - - info.IsExpiredSupporter = info.ExpirationDate.HasValue && info.ExpirationDate < DateTime.UtcNow && !string.IsNullOrWhiteSpace(info.SupporterKey); - - return info; - } - } - /// /// Register an app store sale with our back-end. It will validate the transaction with the store /// and then register the proper feature and then fill in the supporter key on success. diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs index dc642a0a8..014275331 100644 --- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs +++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs @@ -185,7 +185,7 @@ namespace MediaBrowser.Common.Implementations.Updates } } - private Tuple, DateTime> _lastPackageListResult; + private DateTime _lastPackageUpdateTime; /// /// Gets all available packages. @@ -194,40 +194,89 @@ namespace MediaBrowser.Common.Implementations.Updates /// Task{List{PackageInfo}}. public async Task> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken) { - if (_lastPackageListResult != null) + using (var stream = await GetCachedPackages(cancellationToken).ConfigureAwait(false)) { - TimeSpan cacheLength; + var packages = _jsonSerializer.DeserializeFromStream>(stream).ToList(); - switch (_config.CommonConfiguration.SystemUpdateLevel) + if ((DateTime.UtcNow - _lastPackageUpdateTime) > GetCacheLength()) { - case PackageVersionClass.Beta: - cacheLength = TimeSpan.FromMinutes(30); - break; - case PackageVersionClass.Dev: - cacheLength = TimeSpan.FromMinutes(3); - break; - default: - cacheLength = TimeSpan.FromHours(24); - break; + UpdateCachedPackages(CancellationToken.None, false); } - if ((DateTime.UtcNow - _lastPackageListResult.Item2) < cacheLength) - { - return _lastPackageListResult.Item1; - } + return packages; } + } - using (var json = await _httpClient.Get(MbAdmin.HttpUrl + "service/MB3Packages.json", cancellationToken).ConfigureAwait(false)) + private string PackageCachePath + { + get { return Path.Combine(_appPaths.CachePath, "serverpackages.json"); } + } + + private async Task GetCachedPackages(CancellationToken cancellationToken) + { + try + { + return _fileSystem.OpenRead(PackageCachePath); + } + catch (Exception) { - cancellationToken.ThrowIfCancellationRequested(); - var packages = _jsonSerializer.DeserializeFromStream>(json).ToList(); + } - packages = FilterPackages(packages).ToList(); + await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false); + return _fileSystem.OpenRead(PackageCachePath); + } + + private readonly SemaphoreSlim _updateSemaphore = new SemaphoreSlim(1, 1); + private async Task UpdateCachedPackages(CancellationToken cancellationToken, bool throwErrors) + { + await _updateSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - _lastPackageListResult = new Tuple, DateTime>(packages, DateTime.UtcNow); + try + { + if ((DateTime.UtcNow - _lastPackageUpdateTime) < GetCacheLength()) + { + return; + } - return _lastPackageListResult.Item1; + var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions + { + Url = MbAdmin.HttpUrl + "service/MB3Packages.json", + CancellationToken = cancellationToken, + Progress = new Progress() + + }).ConfigureAwait(false); + + _fileSystem.CreateDirectory(Path.GetDirectoryName(PackageCachePath)); + + _fileSystem.CopyFile(tempFile, PackageCachePath, true); + _lastPackageUpdateTime = DateTime.UtcNow; + } + catch (Exception ex) + { + _logger.ErrorException("Error updating package cache", ex); + + if (throwErrors) + { + throw; + } + } + finally + { + _updateSemaphore.Release(); + } + } + + private TimeSpan GetCacheLength() + { + switch (_config.CommonConfiguration.SystemUpdateLevel) + { + case PackageVersionClass.Beta: + return TimeSpan.FromMinutes(30); + case PackageVersionClass.Dev: + return TimeSpan.FromMinutes(3); + default: + return TimeSpan.FromHours(24); } } @@ -554,7 +603,7 @@ namespace MediaBrowser.Common.Implementations.Updates if (packageChecksum != Guid.Empty) // support for legacy uploads for now { using (var crypto = new MD5CryptoServiceProvider()) - using (var stream = new BufferedStream(_fileSystem.OpenRead(tempFile), 100000)) + using (var stream = new BufferedStream(_fileSystem.OpenRead(tempFile), 100000)) { var check = Guid.Parse(BitConverter.ToString(crypto.ComputeHash(stream)).Replace("-", String.Empty)); if (check != packageChecksum) @@ -569,12 +618,12 @@ namespace MediaBrowser.Common.Implementations.Updates // Success - move it to the real target try { - _fileSystem.CreateDirectory(Path.GetDirectoryName(target)); - _fileSystem.CopyFile(tempFile, target, true); + _fileSystem.CreateDirectory(Path.GetDirectoryName(target)); + _fileSystem.CopyFile(tempFile, target, true); //If it is an archive - write out a version file so we know what it is if (isArchive) { - File.WriteAllText(target + ".ver", package.versionStr); + File.WriteAllText(target + ".ver", package.versionStr); } } catch (IOException e) diff --git a/MediaBrowser.Common/Security/ISecurityManager.cs b/MediaBrowser.Common/Security/ISecurityManager.cs index 729de911b..0d8934a62 100644 --- a/MediaBrowser.Common/Security/ISecurityManager.cs +++ b/MediaBrowser.Common/Security/ISecurityManager.cs @@ -41,12 +41,6 @@ namespace MediaBrowser.Common.Security /// Task LoadAllRegistrationInfo(); - /// - /// Gets the supporter information. - /// - /// Task<SupporterInfo>. - Task GetSupporterInfo(); - /// /// Register and app store sale with our back-end /// diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 40e532b79..6145983e2 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -608,9 +608,6 @@ Entities\SortOrder.cs - - Entities\SupporterInfo.cs - Entities\TrailerType.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 09a7cde9d..435c4f50b 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -573,9 +573,6 @@ Entities\SortOrder.cs - - Entities\SupporterInfo.cs - Entities\TrailerType.cs diff --git a/MediaBrowser.Model/Entities/SupporterInfo.cs b/MediaBrowser.Model/Entities/SupporterInfo.cs deleted file mode 100644 index 233d5615f..000000000 --- a/MediaBrowser.Model/Entities/SupporterInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace MediaBrowser.Model.Entities -{ - public class SupporterInfo - { - public string Email { get; set; } - public string SupporterKey { get; set; } - public DateTime? ExpirationDate { get; set; } - public DateTime RegistrationDate { get; set; } - public string PlanType { get; set; } - public bool IsActiveSupporter { get; set; } - public bool IsExpiredSupporter { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 1386854bb..3664175d8 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -144,7 +144,6 @@ - diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 9ad04ebbd..af81b4eea 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -10,6 +10,7 @@ using System.IO; using System.Net; using System.Text; using System.Threading; +using System.Threading.Tasks; using CommonIO; using MediaBrowser.Common.IO; @@ -40,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Connect public void Run() { - LoadCachedAddress(); + Task.Run(() => LoadCachedAddress()); _timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3)); } diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index f1de09d56..fdc7e9ee2 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -1073,11 +1073,6 @@ namespace MediaBrowser.Server.Implementations.Connect public async Task GetConnectSupporterSummary() { - if (!_securityManager.IsMBSupporter) - { - return new ConnectSupporterSummary(); - } - var url = GetConnectUrl("keyAssociation"); var options = new HttpRequestOptions @@ -1106,11 +1101,6 @@ namespace MediaBrowser.Server.Implementations.Connect public async Task AddConnectSupporter(string id) { - if (!_securityManager.IsMBSupporter) - { - throw new InvalidOperationException(); - } - var url = GetConnectUrl("keyAssociation"); var options = new HttpRequestOptions @@ -1139,11 +1129,6 @@ namespace MediaBrowser.Server.Implementations.Connect public async Task RemoveConnectSupporter(string id) { - if (!_securityManager.IsMBSupporter) - { - throw new InvalidOperationException(); - } - var url = GetConnectUrl("keyAssociation"); var options = new HttpRequestOptions diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs b/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs index 27170ced9..701cf21fb 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs @@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints /// public void Run() { - _timer = new Timer(s => LoadAllRegistrations(), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromHours(24)); + _timer = new Timer(s => LoadAllRegistrations(), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromHours(12)); } private async Task LoadAllRegistrations() diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs deleted file mode 100644 index 9a20505a5..000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs +++ /dev/null @@ -1,148 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Notifications; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Notifications; -using MediaBrowser.Model.Serialization; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using CommonIO; - -namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications -{ - public class RemoteNotifications : IServerEntryPoint - { - private const string Url = "http://www.mb3admin.com/admin/service/MB3ServerNotifications.json"; - - private Timer _timer; - private readonly IHttpClient _httpClient; - private readonly IApplicationPaths _appPaths; - private readonly ILogger _logger; - private readonly IJsonSerializer _json; - private readonly IUserManager _userManager; - private readonly IFileSystem _fileSystem; - - private readonly TimeSpan _frequency = TimeSpan.FromHours(6); - private readonly TimeSpan _maxAge = TimeSpan.FromDays(31); - - private readonly INotificationManager _notificationManager; - - public RemoteNotifications(IApplicationPaths appPaths, ILogger logger, IHttpClient httpClient, IJsonSerializer json, IUserManager userManager, IFileSystem fileSystem, INotificationManager notificationManager) - { - _appPaths = appPaths; - _logger = logger; - _httpClient = httpClient; - _json = json; - _userManager = userManager; - _fileSystem = fileSystem; - _notificationManager = notificationManager; - } - - /// - /// Runs this instance. - /// - public void Run() - { - _timer = new Timer(OnTimerFired, null, TimeSpan.FromMilliseconds(500), _frequency); - } - - /// - /// Called when [timer fired]. - /// - /// The state. - private async void OnTimerFired(object state) - { - var dataPath = Path.Combine(_appPaths.DataPath, "remotenotifications.json"); - - var lastRunTime = _fileSystem.FileExists(dataPath) ? _fileSystem.GetLastWriteTimeUtc(dataPath) : DateTime.MinValue; - - try - { - await DownloadNotifications(dataPath, lastRunTime).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error downloading remote notifications", ex); - } - } - - /// - /// Downloads the notifications. - /// - /// The data path. - /// The last run time. - /// Task. - private async Task DownloadNotifications(string dataPath, DateTime lastRunTime) - { - using (var stream = await _httpClient.Get(new HttpRequestOptions - { - Url = Url - - }).ConfigureAwait(false)) - { - var notifications = _json.DeserializeFromStream(stream); - - _fileSystem.WriteAllText(dataPath, string.Empty); - - await CreateNotifications(notifications, lastRunTime).ConfigureAwait(false); - } - } - - /// - /// Creates the notifications. - /// - /// The notifications. - /// The last run time. - /// Task. - private async Task CreateNotifications(IEnumerable notifications, DateTime lastRunTime) - { - // Only show notifications that are active, new since last download, and not older than max age - var notificationList = notifications - .Where(i => string.Equals(i.active, "1") && i.date.ToUniversalTime() > lastRunTime && (DateTime.UtcNow - i.date.ToUniversalTime()) <= _maxAge) - .ToList(); - - var userIds = _userManager.Users.Select(i => i.Id.ToString("N")).ToList(); - - foreach (var notification in notificationList) - { - await _notificationManager.SendNotification(new NotificationRequest - { - Date = notification.date, - Name = notification.name, - Description = notification.description, - Url = notification.url, - UserIds = userIds - - }, CancellationToken.None).ConfigureAwait(false); - } - } - - public void Dispose() - { - if (_timer != null) - { - _timer.Dispose(); - _timer = null; - } - } - - private class RemoteNotification - { - public string id { get; set; } - public DateTime date { get; set; } - public string name { get; set; } - public string description { get; set; } - public string category { get; set; } - public string url { get; set; } - public object imageUrl { get; set; } - public string active { get; set; } - } - } -} diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index bec2abdc4..52adae14c 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -131,7 +131,6 @@ - -- cgit v1.2.3 From 81fb823c024a6652d967bb818cb4fe83417132c4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 11 Jan 2016 11:52:22 -0500 Subject: record mediastream comment --- .../MediaEncoding/IMediaEncoder.cs | 3 +- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 14 +++++----- .../Probing/ProbeResultNormalizer.cs | 1 + MediaBrowser.Model/Entities/MediaStream.cs | 6 ++++ .../MediaInfo/AudioImageProvider.cs | 29 ++++++++++++++------ .../Persistence/MediaStreamColumns.cs | 32 ++++++++++++++++++++++ .../Persistence/SqliteItemRepository.cs | 11 ++++++-- 7 files changed, 78 insertions(+), 18 deletions(-) (limited to 'MediaBrowser.Model/Entities') diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 427af6f6d..76ef054de 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -35,9 +35,10 @@ namespace MediaBrowser.Controller.MediaEncoding /// Extracts the audio image. /// /// The path. + /// Index of the image stream. /// The cancellation token. /// Task{Stream}. - Task ExtractAudioImage(string path, CancellationToken cancellationToken); + Task ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken); /// /// Extracts the video image. diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index f436ca3a0..3c6a99c65 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -472,18 +472,18 @@ namespace MediaBrowser.MediaEncoding.Encoder /// protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - public Task ExtractAudioImage(string path, CancellationToken cancellationToken) + public Task ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken) { - return ExtractImage(new[] { path }, MediaProtocol.File, true, null, null, cancellationToken); + return ExtractImage(new[] { path }, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken); } public Task ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { - return ExtractImage(inputFiles, protocol, false, threedFormat, offset, cancellationToken); + return ExtractImage(inputFiles, null, protocol, false, threedFormat, offset, cancellationToken); } - private async Task ExtractImage(string[] inputFiles, MediaProtocol protocol, bool isAudio, + private async Task ExtractImage(string[] inputFiles, int? imageStreamIndex, MediaProtocol protocol, bool isAudio, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { var resourcePool = isAudio ? _audioImageResourcePool : _videoImageResourcePool; @@ -494,7 +494,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { try { - return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); } catch (ArgumentException) { @@ -506,10 +506,10 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); } - private async Task ExtractImageInternal(string inputPath, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) + private async Task ExtractImageInternal(string inputPath, int? imageStreamIndex, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(inputPath)) { diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index d98efffe7..1df8896d5 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -141,6 +141,7 @@ namespace MediaBrowser.MediaEncoding.Probing if (streamInfo.tags != null) { stream.Language = GetDictionaryValue(streamInfo.tags, "language"); + stream.Comment = GetDictionaryValue(streamInfo.tags, "comment"); } if (string.Equals(streamInfo.codec_type, "audio", StringComparison.OrdinalIgnoreCase)) diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index d089f0aa9..7f4cc2f84 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -30,6 +30,12 @@ namespace MediaBrowser.Model.Entities /// The language. public string Language { get; set; } + /// + /// Gets or sets the comment. + /// + /// The comment. + public string Comment { get; set; } + /// /// Gets or sets a value indicating whether this instance is interlaced. /// diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 8884412d2..c98a67bbd 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using System; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -43,20 +44,27 @@ namespace MediaBrowser.Providers.MediaInfo { var audio = (Audio)item; + var imageStreams = + audio.GetMediaSources(false) + .Take(1) + .SelectMany(i => i.MediaStreams) + .Where(i => i.Type == MediaStreamType.EmbeddedImage) + .ToList(); + // Can't extract if we didn't find a video stream in the file - if (!audio.GetMediaSources(false).Take(1).SelectMany(i => i.MediaStreams).Any(i => i.Type == MediaStreamType.EmbeddedImage)) + if (imageStreams.Count == 0) { return Task.FromResult(new DynamicImageResponse { HasImage = false }); } - return GetImage((Audio)item, cancellationToken); + return GetImage((Audio)item, imageStreams, cancellationToken); } - public async Task GetImage(Audio item, CancellationToken cancellationToken) + public async Task GetImage(Audio item, List imageStreams, CancellationToken cancellationToken) { var path = GetAudioImagePath(item); - if (!_fileSystem.FileExists(path)) + if (!_fileSystem.FileExists(path)) { var semaphore = GetLock(path); @@ -66,11 +74,16 @@ namespace MediaBrowser.Providers.MediaInfo try { // Check again in case it was saved while waiting for the lock - if (!_fileSystem.FileExists(path)) + if (!_fileSystem.FileExists(path)) { - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + + var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("front", StringComparison.OrdinalIgnoreCase) != -1) ?? + imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("cover", StringComparison.OrdinalIgnoreCase) != -1); + + var imageStreamIndex = imageStream == null ? (int?)null : imageStream.Index; - using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, cancellationToken).ConfigureAwait(false)) + using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, imageStreamIndex, cancellationToken).ConfigureAwait(false)) { using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { diff --git a/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs b/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs index c983dd547..7e46db5a7 100644 --- a/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs +++ b/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs @@ -28,6 +28,38 @@ namespace MediaBrowser.Server.Implementations.Persistence AddKeyFramesColumn(); AddRefFramesCommand(); AddCodecTagColumn(); + AddCommentColumn(); + } + + private void AddCommentColumn() + { + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "PRAGMA table_info(mediastreams)"; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + if (!reader.IsDBNull(1)) + { + var name = reader.GetString(1); + + if (string.Equals(name, "Comment", StringComparison.OrdinalIgnoreCase)) + { + return; + } + } + } + } + } + + var builder = new StringBuilder(); + + builder.AppendLine("alter table mediastreams"); + builder.AppendLine("add column Comment TEXT"); + + _connection.RunQueries(new[] { builder.ToString() }, _logger); } private void AddCodecTagColumn() diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 1d3ac293e..3d5ddcf49 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -127,7 +127,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); var createMediaStreamsTableCommand - = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, IsCabac BIT NULL, CodecTag TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; + = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, IsCabac BIT NULL, CodecTag TEXT NULL, Comment TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; string[] queries = { @@ -385,7 +385,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "IsAnamorphic", "RefFrames", "IsCabac", - "CodecTag" + "CodecTag", + "Comment" }; /// @@ -2683,6 +2684,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveStreamCommand.GetParameter(index++).Value = stream.IsCabac; _saveStreamCommand.GetParameter(index++).Value = stream.CodecTag; + _saveStreamCommand.GetParameter(index++).Value = stream.Comment; _saveStreamCommand.Transaction = transaction; _saveStreamCommand.ExecuteNonQuery(); @@ -2841,6 +2843,11 @@ namespace MediaBrowser.Server.Implementations.Persistence item.CodecTag = reader.GetString(26); } + if (!reader.IsDBNull(27)) + { + item.Comment = reader.GetString(27); + } + return item; } -- cgit v1.2.3 From 9f6fcc9e058848e5a07400ebca6c1357947b9336 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 12 Jan 2016 15:49:33 -0500 Subject: capture conductor --- MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs | 10 +++++++++- MediaBrowser.Model/Entities/PersonType.cs | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Model/Entities') diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 1df8896d5..31f6af181 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -441,7 +441,6 @@ namespace MediaBrowser.MediaEncoding.Probing } var composer = FFProbeHelpers.GetDictionaryValue(tags, "composer"); - if (!string.IsNullOrWhiteSpace(composer)) { foreach (var person in Split(composer, false)) @@ -450,6 +449,15 @@ namespace MediaBrowser.MediaEncoding.Probing } } + var conductor = FFProbeHelpers.GetDictionaryValue(tags, "conductor"); + if (!string.IsNullOrWhiteSpace(conductor)) + { + foreach (var person in Split(conductor, false)) + { + audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Conductor }); + } + } + audio.Album = FFProbeHelpers.GetDictionaryValue(tags, "album"); var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists"); diff --git a/MediaBrowser.Model/Entities/PersonType.cs b/MediaBrowser.Model/Entities/PersonType.cs index ee80b1496..bdf846095 100644 --- a/MediaBrowser.Model/Entities/PersonType.cs +++ b/MediaBrowser.Model/Entities/PersonType.cs @@ -30,5 +30,9 @@ namespace MediaBrowser.Model.Entities /// The producer /// public const string Producer = "Producer"; + /// + /// The conductor + /// + public const string Conductor = "Conductor"; } } -- cgit v1.2.3 From 99a21c84b434670c56eb6dcad68c49ee0c3aff22 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Jan 2016 20:35:43 -0500 Subject: add dvbsub as not text --- MediaBrowser.Model/Entities/MediaStream.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'MediaBrowser.Model/Entities') diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 7f4cc2f84..1e19a0601 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -195,6 +195,7 @@ namespace MediaBrowser.Model.Entities return StringHelper.IndexOfIgnoreCase(codec, "pgs") == -1 && StringHelper.IndexOfIgnoreCase(codec, "dvd") == -1 && + StringHelper.IndexOfIgnoreCase(codec, "dvbsub") == -1 && !StringHelper.EqualsIgnoreCase(codec, "sub"); } -- cgit v1.2.3 From 1a2867ea5516989c993e0f01322142d532e6ebc4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 11 Feb 2016 14:11:28 -0500 Subject: support tagging 3d as mvc --- MediaBrowser.Controller/Providers/BaseItemXmlParser.cs | 4 ++++ MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs | 3 +++ MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 2 ++ MediaBrowser.Model/Entities/Video3DFormat.cs | 3 ++- .../Library/Resolvers/BaseVideoResolver.cs | 4 ++++ MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs | 4 ++++ MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs | 3 +++ 7 files changed, 22 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Model/Entities') diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index 3e5353812..f9060d184 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -889,6 +889,10 @@ namespace MediaBrowser.Controller.Providers { video.Video3DFormat = Video3DFormat.FullSideBySide; } + else if (string.Equals("MVC", val, StringComparison.OrdinalIgnoreCase)) + { + video.Video3DFormat = Video3DFormat.MVC; + } } break; } diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs index c9a4cb537..48c4fe2fd 100644 --- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs @@ -736,6 +736,9 @@ namespace MediaBrowser.LocalMetadata.Savers case Video3DFormat.HalfTopAndBottom: builder.Append("HTAB"); break; + case Video3DFormat.MVC: + builder.Append("MVC"); + break; } } } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 2a3a416ad..30e50fecd 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -557,6 +557,8 @@ namespace MediaBrowser.MediaEncoding.Encoder vf = "crop=iw:ih/2:0:0,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1,scale=600:trunc(600/dar/2)*2"; // ftab crop heigt in half, set the display aspect,crop out any black bars we may have made the scale width to 600 break; + default: + break; } } diff --git a/MediaBrowser.Model/Entities/Video3DFormat.cs b/MediaBrowser.Model/Entities/Video3DFormat.cs index 064b02edd..722df4281 100644 --- a/MediaBrowser.Model/Entities/Video3DFormat.cs +++ b/MediaBrowser.Model/Entities/Video3DFormat.cs @@ -6,6 +6,7 @@ namespace MediaBrowser.Model.Entities HalfSideBySide, FullSideBySide, FullTopAndBottom, - HalfTopAndBottom + HalfTopAndBottom, + MVC } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index 9ebf82c02..9edd3f83f 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -242,6 +242,10 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers { video.Video3DFormat = Video3DFormat.HalfTopAndBottom; } + else if (string.Equals(format3D, "mvc", StringComparison.OrdinalIgnoreCase)) + { + video.Video3DFormat = Video3DFormat.MVC; + } } } diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index 40b974ee7..30243ff57 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -1173,6 +1173,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers { video.Video3DFormat = Video3DFormat.FullSideBySide; } + else if (string.Equals("MVC", val, StringComparison.OrdinalIgnoreCase)) + { + video.Video3DFormat = Video3DFormat.MVC; + } } break; } diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index ec12088b3..53a7926ca 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -404,6 +404,9 @@ namespace MediaBrowser.XbmcMetadata.Savers case Video3DFormat.HalfTopAndBottom: writer.WriteElementString("format3d", "HTAB"); break; + case Video3DFormat.MVC: + writer.WriteElementString("format3d", "MVC"); + break; } } } -- cgit v1.2.3