From b82081e4b2da0d165000439a416b5f7cea9c66ec Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 22 Apr 2015 09:28:45 -0400 Subject: [PATCH 01/20] 3.0.5588.1 --- .../LiveTv/LiveTvManager.cs | 2 +- .../Localization/JavaScript/javascript.json | 1 + .../Localization/cultures.json | 1 - ...MediaBrowser.Server.Implementations.csproj | 1 - .../Photos/BaseDynamicImageProvider.cs | 2 +- .../Sync/SyncManager.cs | 52 ++++++++----------- SharedVersion.cs | 4 +- 7 files changed, 28 insertions(+), 35 deletions(-) delete mode 100644 MediaBrowser.Server.Implementations/Localization/cultures.json diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 51f23984a8..6aea6fcaaf 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1040,7 +1040,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv innerProgress.RegisterAction(p => progress.Report(90 + (p * .1))); await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false); - RefreshIfNeeded(GetPrograms().Where(i => (i.StartDate - DateTime.UtcNow).TotalDays <= 1).ToList()); + RefreshIfNeeded(GetPrograms().ToList()); } private async Task RefreshChannelsInternal(IProgress progress, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 49ca737fee..c15e520e26 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -440,6 +440,7 @@ "HeaderVideo": "Video", "HeaderRuntime": "Runtime", "HeaderCommunityRating": "Community rating", + "HeaderPasswordReset": "Password Reset", "HeaderParentalRating": "Parental rating", "HeaderReleaseDate": "Release date", "HeaderDateAdded": "Date added", diff --git a/MediaBrowser.Server.Implementations/Localization/cultures.json b/MediaBrowser.Server.Implementations/Localization/cultures.json deleted file mode 100644 index e9732fda86..0000000000 --- a/MediaBrowser.Server.Implementations/Localization/cultures.json +++ /dev/null @@ -1 +0,0 @@ -[{"Name":"af","DisplayName":"Afrikaans","TwoLetterISOLanguageName":"af","ThreeLetterISOLanguageName":"afr"},{"Name":"sq","DisplayName":"Albanian","TwoLetterISOLanguageName":"sq","ThreeLetterISOLanguageName":"sqi"},{"Name":"gsw","DisplayName":"Alsatian","TwoLetterISOLanguageName":"gsw","ThreeLetterISOLanguageName":"gsw"},{"Name":"am","DisplayName":"Amharic","TwoLetterISOLanguageName":"am","ThreeLetterISOLanguageName":"amh"},{"Name":"ar","DisplayName":"Arabic","TwoLetterISOLanguageName":"ar","ThreeLetterISOLanguageName":"ara"},{"Name":"hy","DisplayName":"Armenian","TwoLetterISOLanguageName":"hy","ThreeLetterISOLanguageName":"hye"},{"Name":"as","DisplayName":"Assamese","TwoLetterISOLanguageName":"as","ThreeLetterISOLanguageName":"asm"},{"Name":"az","DisplayName":"Azeri","TwoLetterISOLanguageName":"az","ThreeLetterISOLanguageName":"aze"},{"Name":"jv","DisplayName":"Basa Jawa","TwoLetterISOLanguageName":"jv","ThreeLetterISOLanguageName":"jav"},{"Name":"ba","DisplayName":"Bashkir","TwoLetterISOLanguageName":"ba","ThreeLetterISOLanguageName":"bak"},{"Name":"eu","DisplayName":"Basque","TwoLetterISOLanguageName":"eu","ThreeLetterISOLanguageName":"eus"},{"Name":"be","DisplayName":"Belarusian","TwoLetterISOLanguageName":"be","ThreeLetterISOLanguageName":"bel"},{"Name":"bn","DisplayName":"Bengali","TwoLetterISOLanguageName":"bn","ThreeLetterISOLanguageName":"bng"},{"Name":"bs","DisplayName":"Bosnian","TwoLetterISOLanguageName":"bs","ThreeLetterISOLanguageName":"bsb"},{"Name":"bs-Cyrl","DisplayName":"Bosnian (Cyrillic)","TwoLetterISOLanguageName":"bs","ThreeLetterISOLanguageName":"bsc"},{"Name":"br","DisplayName":"Breton","TwoLetterISOLanguageName":"br","ThreeLetterISOLanguageName":"bre"},{"Name":"bg","DisplayName":"Bulgarian","TwoLetterISOLanguageName":"bg","ThreeLetterISOLanguageName":"bul"},{"Name":"my","DisplayName":"Burmese","TwoLetterISOLanguageName":"my","ThreeLetterISOLanguageName":"mya"},{"Name":"ca","DisplayName":"Catalan","TwoLetterISOLanguageName":"ca","ThreeLetterISOLanguageName":"cat"},{"Name":"tzm-Tfng-MA","DisplayName":"Central Atlas Tamazight (Tifinagh, Morocco)","TwoLetterISOLanguageName":"tzm","ThreeLetterISOLanguageName":"tzm"},{"Name":"ku","DisplayName":"Central Kurdish","TwoLetterISOLanguageName":"ku","ThreeLetterISOLanguageName":"kur"},{"Name":"chr","DisplayName":"Cherokee","TwoLetterISOLanguageName":"chr","ThreeLetterISOLanguageName":"chr"},{"Name":"zh","DisplayName":"Chinese","TwoLetterISOLanguageName":"zh","ThreeLetterISOLanguageName":"zho"},{"Name":"sn","DisplayName":"chiShona","TwoLetterISOLanguageName":"sn","ThreeLetterISOLanguageName":"sna"},{"Name":"co","DisplayName":"Corsican","TwoLetterISOLanguageName":"co","ThreeLetterISOLanguageName":"cos"},{"Name":"hr","DisplayName":"Croatian","TwoLetterISOLanguageName":"hr","ThreeLetterISOLanguageName":"hrv"},{"Name":"hr-BA","DisplayName":"Croatian (Latin, Bosnia and Herzegovina)","TwoLetterISOLanguageName":"hr","ThreeLetterISOLanguageName":"hrb"},{"Name":"cs","DisplayName":"Czech","TwoLetterISOLanguageName":"cs","ThreeLetterISOLanguageName":"ces"},{"Name":"da","DisplayName":"Danish","TwoLetterISOLanguageName":"da","ThreeLetterISOLanguageName":"dan"},{"Name":"prs","DisplayName":"Dari","TwoLetterISOLanguageName":"prs","ThreeLetterISOLanguageName":"prs"},{"Name":"dv","DisplayName":"Divehi","TwoLetterISOLanguageName":"dv","ThreeLetterISOLanguageName":"div"},{"Name":"nl","DisplayName":"Dutch","TwoLetterISOLanguageName":"nl","ThreeLetterISOLanguageName":"nld"},{"Name":"en","DisplayName":"English","TwoLetterISOLanguageName":"en","ThreeLetterISOLanguageName":"eng"},{"Name":"et","DisplayName":"Estonian","TwoLetterISOLanguageName":"et","ThreeLetterISOLanguageName":"est"},{"Name":"fo","DisplayName":"Faroese","TwoLetterISOLanguageName":"fo","ThreeLetterISOLanguageName":"fao"},{"Name":"fil","DisplayName":"Filipino","TwoLetterISOLanguageName":"fil","ThreeLetterISOLanguageName":"fil"},{"Name":"fi","DisplayName":"Finnish","TwoLetterISOLanguageName":"fi","ThreeLetterISOLanguageName":"fin"},{"Name":"fr","DisplayName":"French","TwoLetterISOLanguageName":"fr","ThreeLetterISOLanguageName":"fra"},{"Name":"fy","DisplayName":"Frisian","TwoLetterISOLanguageName":"fy","ThreeLetterISOLanguageName":"fry"},{"Name":"ff","DisplayName":"Fulah","TwoLetterISOLanguageName":"ff","ThreeLetterISOLanguageName":"ful"},{"Name":"gl","DisplayName":"Galician","TwoLetterISOLanguageName":"gl","ThreeLetterISOLanguageName":"glg"},{"Name":"ka","DisplayName":"Georgian","TwoLetterISOLanguageName":"ka","ThreeLetterISOLanguageName":"kat"},{"Name":"de","DisplayName":"German","TwoLetterISOLanguageName":"de","ThreeLetterISOLanguageName":"deu"},{"Name":"el","DisplayName":"Greek","TwoLetterISOLanguageName":"el","ThreeLetterISOLanguageName":"ell"},{"Name":"kl","DisplayName":"Greenlandic","TwoLetterISOLanguageName":"kl","ThreeLetterISOLanguageName":"kal"},{"Name":"gn","DisplayName":"Guarani","TwoLetterISOLanguageName":"gn","ThreeLetterISOLanguageName":"grn"},{"Name":"gu","DisplayName":"Gujarati","TwoLetterISOLanguageName":"gu","ThreeLetterISOLanguageName":"guj"},{"Name":"ha","DisplayName":"Hausa","TwoLetterISOLanguageName":"ha","ThreeLetterISOLanguageName":"hau"},{"Name":"haw","DisplayName":"Hawaiian","TwoLetterISOLanguageName":"haw","ThreeLetterISOLanguageName":"haw"},{"Name":"he","DisplayName":"Hebrew","TwoLetterISOLanguageName":"he","ThreeLetterISOLanguageName":"heb"},{"Name":"hi","DisplayName":"Hindi","TwoLetterISOLanguageName":"hi","ThreeLetterISOLanguageName":"hin"},{"Name":"hu","DisplayName":"Hungarian","TwoLetterISOLanguageName":"hu","ThreeLetterISOLanguageName":"hun"},{"Name":"is","DisplayName":"Icelandic","TwoLetterISOLanguageName":"is","ThreeLetterISOLanguageName":"isl"},{"Name":"ig","DisplayName":"Igbo","TwoLetterISOLanguageName":"ig","ThreeLetterISOLanguageName":"ibo"},{"Name":"id","DisplayName":"Indonesian","TwoLetterISOLanguageName":"id","ThreeLetterISOLanguageName":"ind"},{"Name":"iu","DisplayName":"Inuktitut","TwoLetterISOLanguageName":"iu","ThreeLetterISOLanguageName":"iku"},{"Name":"ga","DisplayName":"Irish","TwoLetterISOLanguageName":"ga","ThreeLetterISOLanguageName":"gle"},{"Name":"xh","DisplayName":"isiXhosa","TwoLetterISOLanguageName":"xh","ThreeLetterISOLanguageName":"xho"},{"Name":"zu","DisplayName":"isiZulu","TwoLetterISOLanguageName":"zu","ThreeLetterISOLanguageName":"zul"},{"Name":"it","DisplayName":"Italian","TwoLetterISOLanguageName":"it","ThreeLetterISOLanguageName":"ita"},{"Name":"ja","DisplayName":"Japanese","TwoLetterISOLanguageName":"ja","ThreeLetterISOLanguageName":"jpn"},{"Name":"kn","DisplayName":"Kannada","TwoLetterISOLanguageName":"kn","ThreeLetterISOLanguageName":"kan"},{"Name":"kk","DisplayName":"Kazakh","TwoLetterISOLanguageName":"kk","ThreeLetterISOLanguageName":"kaz"},{"Name":"km","DisplayName":"Khmer","TwoLetterISOLanguageName":"km","ThreeLetterISOLanguageName":"khm"},{"Name":"qut","DisplayName":"K'iche","TwoLetterISOLanguageName":"qut","ThreeLetterISOLanguageName":"qut"},{"Name":"rw","DisplayName":"Kinyarwanda","TwoLetterISOLanguageName":"rw","ThreeLetterISOLanguageName":"kin"},{"Name":"sw","DisplayName":"Kiswahili","TwoLetterISOLanguageName":"sw","ThreeLetterISOLanguageName":"swa"},{"Name":"kok","DisplayName":"Konkani","TwoLetterISOLanguageName":"kok","ThreeLetterISOLanguageName":"kok"},{"Name":"ko","DisplayName":"Korean","TwoLetterISOLanguageName":"ko","ThreeLetterISOLanguageName":"kor"},{"Name":"ky","DisplayName":"Kyrgyz","TwoLetterISOLanguageName":"ky","ThreeLetterISOLanguageName":"kir"},{"Name":"lo","DisplayName":"Lao","TwoLetterISOLanguageName":"lo","ThreeLetterISOLanguageName":"lao"},{"Name":"lv","DisplayName":"Latvian","TwoLetterISOLanguageName":"lv","ThreeLetterISOLanguageName":"lav"},{"Name":"lt","DisplayName":"Lithuanian","TwoLetterISOLanguageName":"lt","ThreeLetterISOLanguageName":"lit"},{"Name":"dsb","DisplayName":"Lower Sorbian","TwoLetterISOLanguageName":"dsb","ThreeLetterISOLanguageName":"dsb"},{"Name":"lb","DisplayName":"Luxembourgish","TwoLetterISOLanguageName":"lb","ThreeLetterISOLanguageName":"ltz"},{"Name":"mk-MK","DisplayName":"Macedonian (Former Yugoslav Republic of Macedonia)","TwoLetterISOLanguageName":"mk","ThreeLetterISOLanguageName":"mkd"},{"Name":"mg","DisplayName":"Malagasy","TwoLetterISOLanguageName":"mg","ThreeLetterISOLanguageName":"mlg"},{"Name":"ms","DisplayName":"Malay","TwoLetterISOLanguageName":"ms","ThreeLetterISOLanguageName":"msa"},{"Name":"ml","DisplayName":"Malayalam","TwoLetterISOLanguageName":"ml","ThreeLetterISOLanguageName":"mym"},{"Name":"mt","DisplayName":"Maltese","TwoLetterISOLanguageName":"mt","ThreeLetterISOLanguageName":"mlt"},{"Name":"mi","DisplayName":"Maori","TwoLetterISOLanguageName":"mi","ThreeLetterISOLanguageName":"mri"},{"Name":"arn","DisplayName":"Mapudungun","TwoLetterISOLanguageName":"arn","ThreeLetterISOLanguageName":"arn"},{"Name":"mr","DisplayName":"Marathi","TwoLetterISOLanguageName":"mr","ThreeLetterISOLanguageName":"mar"},{"Name":"moh","DisplayName":"Mohawk","TwoLetterISOLanguageName":"moh","ThreeLetterISOLanguageName":"moh"},{"Name":"mn","DisplayName":"Mongolian","TwoLetterISOLanguageName":"mn","ThreeLetterISOLanguageName":"mon"},{"Name":"ne","DisplayName":"Nepali","TwoLetterISOLanguageName":"ne","ThreeLetterISOLanguageName":"nep"},{"Name":"no","DisplayName":"Norwegian","TwoLetterISOLanguageName":"nb","ThreeLetterISOLanguageName":"nob"},{"Name":"nn","DisplayName":"Norwegian (Nynorsk)","TwoLetterISOLanguageName":"nn","ThreeLetterISOLanguageName":"nno"},{"Name":"oc","DisplayName":"Occitan","TwoLetterISOLanguageName":"oc","ThreeLetterISOLanguageName":"oci"},{"Name":"or","DisplayName":"Oriya","TwoLetterISOLanguageName":"or","ThreeLetterISOLanguageName":"ori"},{"Name":"om","DisplayName":"Oromo","TwoLetterISOLanguageName":"om","ThreeLetterISOLanguageName":"orm"},{"Name":"ps","DisplayName":"Pashto","TwoLetterISOLanguageName":"ps","ThreeLetterISOLanguageName":"pus"},{"Name":"fa","DisplayName":"Persian","TwoLetterISOLanguageName":"fa","ThreeLetterISOLanguageName":"fas"},{"Name":"pl","DisplayName":"Polish","TwoLetterISOLanguageName":"pl","ThreeLetterISOLanguageName":"pol"},{"Name":"pt-AO","DisplayName":"português (Angola)","TwoLetterISOLanguageName":"pt","ThreeLetterISOLanguageName":"por"},{"Name":"pa","DisplayName":"Punjabi","TwoLetterISOLanguageName":"pa","ThreeLetterISOLanguageName":"pan"},{"Name":"quz","DisplayName":"Quechua","TwoLetterISOLanguageName":"quz","ThreeLetterISOLanguageName":"qub"},{"Name":"quz-EC","DisplayName":"Quechua (Ecuador)","TwoLetterISOLanguageName":"quz","ThreeLetterISOLanguageName":"que"},{"Name":"quz-PE","DisplayName":"Quechua (Peru)","TwoLetterISOLanguageName":"quz","ThreeLetterISOLanguageName":"qup"},{"Name":"ro","DisplayName":"Romanian","TwoLetterISOLanguageName":"ro","ThreeLetterISOLanguageName":"ron"},{"Name":"rm","DisplayName":"Romansh","TwoLetterISOLanguageName":"rm","ThreeLetterISOLanguageName":"roh"},{"Name":"ru","DisplayName":"Russian","TwoLetterISOLanguageName":"ru","ThreeLetterISOLanguageName":"rus"},{"Name":"sah","DisplayName":"Sakha","TwoLetterISOLanguageName":"sah","ThreeLetterISOLanguageName":"sah"},{"Name":"smn","DisplayName":"Sami (Inari)","TwoLetterISOLanguageName":"smn","ThreeLetterISOLanguageName":"smn"},{"Name":"smj","DisplayName":"Sami (Lule)","TwoLetterISOLanguageName":"smj","ThreeLetterISOLanguageName":"smj"},{"Name":"se","DisplayName":"Sami (Northern)","TwoLetterISOLanguageName":"se","ThreeLetterISOLanguageName":"sme"},{"Name":"sms","DisplayName":"Sami (Skolt)","TwoLetterISOLanguageName":"sms","ThreeLetterISOLanguageName":"sms"},{"Name":"sma","DisplayName":"Sami (Southern)","TwoLetterISOLanguageName":"sma","ThreeLetterISOLanguageName":"sma"},{"Name":"sa","DisplayName":"Sanskrit","TwoLetterISOLanguageName":"sa","ThreeLetterISOLanguageName":"san"},{"Name":"gd","DisplayName":"Scottish Gaelic","TwoLetterISOLanguageName":"gd","ThreeLetterISOLanguageName":"gla"},{"Name":"sr","DisplayName":"Serbian","TwoLetterISOLanguageName":"sr","ThreeLetterISOLanguageName":"srp"},{"Name":"sr-Cyrl-BA","DisplayName":"Serbian (Cyrillic, Bosnia and Herzegovina)","TwoLetterISOLanguageName":"sr","ThreeLetterISOLanguageName":"srn"},{"Name":"sr-Latn-BA","DisplayName":"Serbian (Latin, Bosnia and Herzegovina)","TwoLetterISOLanguageName":"sr","ThreeLetterISOLanguageName":"srs"},{"Name":"nso","DisplayName":"Sesotho sa Leboa","TwoLetterISOLanguageName":"nso","ThreeLetterISOLanguageName":"nso"},{"Name":"tn","DisplayName":"Setswana","TwoLetterISOLanguageName":"tn","ThreeLetterISOLanguageName":"tsn"},{"Name":"sd","DisplayName":"Sindhi","TwoLetterISOLanguageName":"sd","ThreeLetterISOLanguageName":"sin"},{"Name":"si","DisplayName":"Sinhala","TwoLetterISOLanguageName":"si","ThreeLetterISOLanguageName":"sin"},{"Name":"sk","DisplayName":"Slovak","TwoLetterISOLanguageName":"sk","ThreeLetterISOLanguageName":"slk"},{"Name":"sl","DisplayName":"Slovenian","TwoLetterISOLanguageName":"sl","ThreeLetterISOLanguageName":"slv"},{"Name":"so","DisplayName":"Somali","TwoLetterISOLanguageName":"so","ThreeLetterISOLanguageName":"som"},{"Name":"st","DisplayName":"Southern Sotho","TwoLetterISOLanguageName":"st","ThreeLetterISOLanguageName":"sot"},{"Name":"es","DisplayName":"Spanish","TwoLetterISOLanguageName":"es","ThreeLetterISOLanguageName":"spa"},{"Name":"zgh","DisplayName":"Standard Morrocan Tamazight","TwoLetterISOLanguageName":"zgh","ThreeLetterISOLanguageName":"zgh"},{"Name":"sv","DisplayName":"Swedish","TwoLetterISOLanguageName":"sv","ThreeLetterISOLanguageName":"swe"},{"Name":"syr","DisplayName":"Syriac","TwoLetterISOLanguageName":"syr","ThreeLetterISOLanguageName":"syr"},{"Name":"tg","DisplayName":"Tajik","TwoLetterISOLanguageName":"tg","ThreeLetterISOLanguageName":"tgk"},{"Name":"ta","DisplayName":"Tamil","TwoLetterISOLanguageName":"ta","ThreeLetterISOLanguageName":"tam"},{"Name":"tt","DisplayName":"Tatar","TwoLetterISOLanguageName":"tt","ThreeLetterISOLanguageName":"tat"},{"Name":"te","DisplayName":"Telugu","TwoLetterISOLanguageName":"te","ThreeLetterISOLanguageName":"tel"},{"Name":"th","DisplayName":"Thai","TwoLetterISOLanguageName":"th","ThreeLetterISOLanguageName":"tha"},{"Name":"bo","DisplayName":"Tibetan","TwoLetterISOLanguageName":"bo","ThreeLetterISOLanguageName":"bod"},{"Name":"ti","DisplayName":"Tigrinya","TwoLetterISOLanguageName":"ti","ThreeLetterISOLanguageName":"tir"},{"Name":"ts","DisplayName":"Tsonga","TwoLetterISOLanguageName":"ts","ThreeLetterISOLanguageName":"tso"},{"Name":"tr","DisplayName":"Turkish","TwoLetterISOLanguageName":"tr","ThreeLetterISOLanguageName":"tur"},{"Name":"tk","DisplayName":"Turkmen","TwoLetterISOLanguageName":"tk","ThreeLetterISOLanguageName":"tuk"},{"Name":"uk","DisplayName":"Ukrainian","TwoLetterISOLanguageName":"uk","ThreeLetterISOLanguageName":"ukr"},{"Name":"hsb","DisplayName":"Upper Sorbian","TwoLetterISOLanguageName":"hsb","ThreeLetterISOLanguageName":"hsb"},{"Name":"ur","DisplayName":"Urdu","TwoLetterISOLanguageName":"ur","ThreeLetterISOLanguageName":"urd"},{"Name":"ug","DisplayName":"Uyghur","TwoLetterISOLanguageName":"ug","ThreeLetterISOLanguageName":"uig"},{"Name":"uz","DisplayName":"Uzbek","TwoLetterISOLanguageName":"uz","ThreeLetterISOLanguageName":"uzb"},{"Name":"vi","DisplayName":"Vietnamese","TwoLetterISOLanguageName":"vi","ThreeLetterISOLanguageName":"vie"},{"Name":"cy","DisplayName":"Welsh","TwoLetterISOLanguageName":"cy","ThreeLetterISOLanguageName":"cym"},{"Name":"wo","DisplayName":"Wolof","TwoLetterISOLanguageName":"wo","ThreeLetterISOLanguageName":"wol"},{"Name":"ii","DisplayName":"Yi","TwoLetterISOLanguageName":"ii","ThreeLetterISOLanguageName":"iii"},{"Name":"yo","DisplayName":"Yoruba","TwoLetterISOLanguageName":"yo","ThreeLetterISOLanguageName":"yor"}] \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 0d545fb6a5..c47759e964 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -401,7 +401,6 @@ - diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs index fd4d5eb27d..15c43213f7 100644 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs @@ -234,7 +234,7 @@ namespace MediaBrowser.Server.Implementations.Photos protected virtual List GetFinalItems(List items, int limit) { // Rotate the images once every x days - var random = DateTime.Now.DayOfYear % 4; + var random = DateTime.Now.DayOfYear % 5; return items .OrderBy(i => (random + "" + items.IndexOf(i)).GetMD5()) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 235c36e8c4..0e4a3bcf13 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -512,7 +512,7 @@ namespace MediaBrowser.Server.Implementations.Sync var video = item as Video; if (video != null) { - if (video.VideoType == VideoType.Iso || video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd || video.VideoType == VideoType.HdDvd) + if (video.VideoType == VideoType.Iso || video.VideoType == VideoType.HdDvd) { return false; } @@ -758,6 +758,8 @@ namespace MediaBrowser.Server.Implementations.Sync var requiresSaving = false; var removeFromDevice = false; + var libraryItem = _libraryManager.GetItemById(jobItem.ItemId); + if (request.LocalItemIds.Contains(jobItem.ItemId, StringComparer.OrdinalIgnoreCase)) { var job = _repo.GetJob(jobItem.JobId); @@ -775,23 +777,18 @@ namespace MediaBrowser.Server.Implementations.Sync _logger.Debug("Adding ItemIdsToRemove {0} because the user is no longer valid.", jobItem.ItemId); removeFromDevice = true; } + else if (!IsLibraryItemAvailable(libraryItem)) + { + // Tell the device to remove it since it's no longer available + _logger.Debug("Adding ItemIdsToRemove {0} because it is no longer available.", jobItem.ItemId); + removeFromDevice = true; + } else if (job.UnwatchedOnly) { - var libraryItem = _libraryManager.GetItemById(jobItem.ItemId); - - if (IsLibraryItemAvailable(libraryItem)) + if (libraryItem.IsPlayed(user) && libraryItem is Video) { - if (libraryItem.IsPlayed(user) && libraryItem is Video) - { - // Tell the device to remove it since it has been played - _logger.Debug("Adding ItemIdsToRemove {0} because it has been marked played.", jobItem.ItemId); - removeFromDevice = true; - } - } - else - { - // Tell the device to remove it since it's no longer available - _logger.Debug("Adding ItemIdsToRemove {0} because it is no longer available.", jobItem.ItemId); + // Tell the device to remove it since it has been played + _logger.Debug("Adding ItemIdsToRemove {0} because it has been marked played.", jobItem.ItemId); removeFromDevice = true; } } @@ -866,6 +863,8 @@ namespace MediaBrowser.Server.Implementations.Sync var requiresSaving = false; var removeFromDevice = false; + var libraryItem = _libraryManager.GetItemById(jobItem.ItemId); + if (request.SyncJobItemIds.Contains(jobItem.Id, StringComparer.OrdinalIgnoreCase)) { var job = _repo.GetJob(jobItem.JobId); @@ -883,23 +882,18 @@ namespace MediaBrowser.Server.Implementations.Sync _logger.Debug("Adding ItemIdsToRemove {0} because the user is no longer valid.", jobItem.Id); removeFromDevice = true; } + else if (!IsLibraryItemAvailable(libraryItem)) + { + // Tell the device to remove it since it's no longer available + _logger.Debug("Adding ItemIdsToRemove {0} because it is no longer available.", jobItem.Id); + removeFromDevice = true; + } else if (job.UnwatchedOnly) { - var libraryItem = _libraryManager.GetItemById(jobItem.ItemId); - - if (IsLibraryItemAvailable(libraryItem)) + if (libraryItem.IsPlayed(user) && libraryItem is Video) { - if (libraryItem.IsPlayed(user) && libraryItem is Video) - { - // Tell the device to remove it since it has been played - _logger.Debug("Adding ItemIdsToRemove {0} because it has been marked played.", jobItem.Id); - removeFromDevice = true; - } - } - else - { - // Tell the device to remove it since it's no longer available - _logger.Debug("Adding ItemIdsToRemove {0} because it is no longer available.", jobItem.Id); + // Tell the device to remove it since it has been played + _logger.Debug("Adding ItemIdsToRemove {0} because it has been marked played.", jobItem.Id); removeFromDevice = true; } } diff --git a/SharedVersion.cs b/SharedVersion.cs index f4ee55b0b2..ef66190171 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.0.*")] -//[assembly: AssemblyVersion("3.0.5588.0")] +//[assembly: AssemblyVersion("3.0.*")] +[assembly: AssemblyVersion("3.0.5588.1")] From ca13b01daa106ad816809d7624a7b46c58e780e2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 22 Apr 2015 09:54:58 -0400 Subject: [PATCH 02/20] increment version --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index ef66190171..1469ab6395 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5588.1")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5588.1")] From e14fa7d8e5b8c97eafec6670797958593e4506f8 Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 22 Apr 2015 10:03:17 -0400 Subject: [PATCH 03/20] update mac build --- MediaBrowser.Server.Mac/Emby.Server.Mac.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 8592fc460e..d1a24ab127 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -538,6 +538,9 @@ Resources\dashboard-ui\nowplaying.html + + Resources\dashboard-ui\photos.html + Resources\dashboard-ui\playbackconfiguration.html @@ -1444,6 +1447,9 @@ Resources\dashboard-ui\scripts\nowplayingpage.js + + Resources\dashboard-ui\scripts\photos.js + Resources\dashboard-ui\scripts\playbackconfiguration.js From 6f016525208f665502d844d151c31e9ff38fd20a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 23 Apr 2015 12:50:54 -0400 Subject: [PATCH 04/20] control the number of simultaneous image operations --- Emby.Drawing/ImageProcessor.cs | 49 ++++++++++++++++++- .../Drawing/IImageProcessor.cs | 2 +- .../Configuration/EncodingOptions.cs | 2 +- .../EntryPoints/ExternalPortForwarding.cs | 22 ++++----- .../Library/UserManager.cs | 16 ++---- .../Photos/BaseDynamicImageProvider.cs | 34 ++++++------- .../UserViews/DynamicImageProvider.cs | 6 +-- 7 files changed, 84 insertions(+), 47 deletions(-) diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 55c6f6455e..6365bd2940 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -51,6 +51,7 @@ namespace Emby.Drawing private readonly IJsonSerializer _jsonSerializer; private readonly IServerApplicationPaths _appPaths; private readonly IImageEncoder _imageEncoder; + private readonly SemaphoreSlim _imageProcessingSemaphore; public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IImageEncoder imageEncoder) { @@ -88,6 +89,8 @@ namespace Emby.Drawing } _cachedImagedSizes = new ConcurrentDictionary(sizeDictionary); + var count = Environment.ProcessorCount; + _imageProcessingSemaphore = new SemaphoreSlim(count, count); } public string[] SupportedInputFormats @@ -201,6 +204,8 @@ namespace Emby.Drawing await semaphore.WaitAsync().ConfigureAwait(false); + var imageProcessingLockTaken = false; + try { CheckDisposed(); @@ -212,11 +217,20 @@ namespace Emby.Drawing Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); + await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); + + imageProcessingLockTaken = true; + _imageEncoder.EncodeImage(originalImagePath, cacheFilePath, newWidth, newHeight, quality, options); } } finally { + if (imageProcessingLockTaken) + { + _imageProcessingSemaphore.Release(); + } + semaphore.Release(); } @@ -254,10 +268,15 @@ namespace Emby.Drawing return GetResult(croppedImagePath); } + var imageProcessingLockTaken = false; + try { Directory.CreateDirectory(Path.GetDirectoryName(croppedImagePath)); + await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); + imageProcessingLockTaken = true; + _imageEncoder.CropWhiteSpace(originalImagePath, croppedImagePath); } catch (Exception ex) @@ -269,6 +288,11 @@ namespace Emby.Drawing } finally { + if (imageProcessingLockTaken) + { + _imageProcessingSemaphore.Release(); + } + semaphore.Release(); } @@ -592,13 +616,25 @@ namespace Emby.Drawing return enhancedImagePath; } + var imageProcessingLockTaken = false; + try { Directory.CreateDirectory(Path.GetDirectoryName(enhancedImagePath)); + + await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); + + imageProcessingLockTaken = true; + await ExecuteImageEnhancers(supportedEnhancers, originalImagePath, enhancedImagePath, item, imageType, imageIndex).ConfigureAwait(false); } finally { + if (imageProcessingLockTaken) + { + _imageProcessingSemaphore.Release(); + } + semaphore.Release(); } @@ -717,9 +753,18 @@ namespace Emby.Drawing return Path.Combine(path, filename); } - public void CreateImageCollage(ImageCollageOptions options) + public async Task CreateImageCollage(ImageCollageOptions options) { - _imageEncoder.CreateImageCollage(options); + await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); + + try + { + _imageEncoder.CreateImageCollage(options); + } + finally + { + _imageProcessingSemaphore.Release(); + } } public IEnumerable GetSupportedEnhancers(IHasImages item, ImageType imageType) diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index 685d2706da..aeb8173921 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -104,6 +104,6 @@ namespace MediaBrowser.Controller.Drawing /// Creates the image collage. /// /// The options. - void CreateImageCollage(ImageCollageOptions options); + Task CreateImageCollage(ImageCollageOptions options); } } diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index c44a7c94d2..afd67eb153 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Model.Configuration DownMixAudioBoost = 2; EncodingQuality = EncodingQuality.Auto; EnableThrottling = true; - ThrottleThresholdSeconds = 90; + ThrottleThresholdSeconds = 120; } } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 3fa0df7608..2106a58dee 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -88,7 +88,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints NatUtility.UnhandledException += NatUtility_UnhandledException; NatUtility.StartDiscovery(); - _timer = new Timer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3)); + _timer = new Timer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); _lastConfigIdentifier = GetConfigIdentifier(); @@ -97,17 +97,17 @@ namespace MediaBrowser.Server.Implementations.EntryPoints void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e) { - //var ex = e.ExceptionObject as Exception; + var ex = e.ExceptionObject as Exception; - //if (ex == null) - //{ - // _logger.Error("Unidentified error reported by Mono.Nat"); - //} - //else - //{ - // // Seeing some blank exceptions coming through here - // _logger.ErrorException("Error reported by Mono.Nat: ", ex); - //} + if (ex == null) + { + //_logger.Error("Unidentified error reported by Mono.Nat"); + } + else + { + // Seeing some blank exceptions coming through here + _logger.ErrorException("Error reported by Mono.Nat: ", ex); + } } void NatUtility_DeviceFound(object sender, DeviceEventArgs e) diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 03471a8e9b..02e1795f36 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -345,7 +345,7 @@ namespace MediaBrowser.Server.Implementations.Library { var name = MakeValidUsername(Environment.UserName); - var user = InstantiateNewUser(name, false); + var user = InstantiateNewUser(name); user.DateLastSaved = DateTime.UtcNow; @@ -552,7 +552,7 @@ namespace MediaBrowser.Server.Implementations.Library try { - var user = InstantiateNewUser(name, true); + var user = InstantiateNewUser(name); var list = Users.ToList(); list.Add(user); @@ -697,21 +697,13 @@ namespace MediaBrowser.Server.Implementations.Library /// Instantiates the new user. /// /// The name. - /// if set to true [check identifier]. /// User. - private User InstantiateNewUser(string name, bool checkId) + private User InstantiateNewUser(string name) { - var id = ("MBUser" + name).GetMD5(); - - if (checkId && Users.Select(i => i.Id).Contains(id)) - { - id = Guid.NewGuid(); - } - return new User { Name = name, - Id = id, + Id = Guid.NewGuid(), DateCreated = DateTime.UtcNow, DateModified = DateTime.UtcNow, UsesIdForConfigurationPath = true diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs index 15c43213f7..be71a6408a 100644 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs @@ -80,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.Photos { var outputPath = Path.Combine(ApplicationPaths.TempDirectory, Guid.NewGuid() + ".png"); Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); - var imageCreated = CreateImage(item, itemsWithImages, outputPath, imageType, 0); + var imageCreated = await CreateImage(item, itemsWithImages, outputPath, imageType, 0).ConfigureAwait(false); if (!imageCreated) { @@ -103,9 +103,9 @@ namespace MediaBrowser.Server.Implementations.Photos return parts.GetMD5().ToString("N"); } - protected void CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, bool drawText) + protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, bool drawText) { - CreateCollage(primaryItem, items, outputPath, 960, 540, drawText, primaryItem.Name); + return CreateCollage(primaryItem, items, outputPath, 960, 540, drawText, primaryItem.Name); } protected virtual IEnumerable GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable items) @@ -115,22 +115,22 @@ namespace MediaBrowser.Server.Implementations.Photos .Where(i => !string.IsNullOrWhiteSpace(i)); } - protected void CreatePosterCollage(IHasImages primaryItem, List items, string outputPath) + protected Task CreatePosterCollage(IHasImages primaryItem, List items, string outputPath) { - CreateCollage(primaryItem, items, outputPath, 600, 900, true, primaryItem.Name); + return CreateCollage(primaryItem, items, outputPath, 600, 900, true, primaryItem.Name); } - protected void CreateSquareCollage(IHasImages primaryItem, List items, string outputPath, bool drawText) + protected Task CreateSquareCollage(IHasImages primaryItem, List items, string outputPath, bool drawText) { - CreateCollage(primaryItem, items, outputPath, 800, 800, drawText, primaryItem.Name); + return CreateCollage(primaryItem, items, outputPath, 800, 800, drawText, primaryItem.Name); } - protected void CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, int width, int height, bool drawText, string text) + protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, int width, int height, bool drawText, string text) { - CreateCollage(primaryItem, items, outputPath, width, height, drawText, text); + return CreateCollage(primaryItem, items, outputPath, width, height, drawText, text); } - private void CreateCollage(IHasImages primaryItem, List items, string outputPath, int width, int height, bool drawText, string text) + private Task CreateCollage(IHasImages primaryItem, List items, string outputPath, int width, int height, bool drawText, string text) { Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); @@ -143,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.Photos InputPaths = GetStripCollageImagePaths(primaryItem, items).ToArray() }; - ImageProcessor.CreateImageCollage(options); + return ImageProcessor.CreateImageCollage(options); } public string Name @@ -151,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.Photos get { return "Dynamic Image Provider"; } } - protected virtual bool CreateImage(IHasImages item, + protected virtual async Task CreateImage(IHasImages item, List itemsWithImages, string outputPath, ImageType imageType, @@ -166,7 +166,7 @@ namespace MediaBrowser.Server.Implementations.Photos if (imageType == ImageType.Thumb) { - CreateThumbCollage(item, itemsWithImages, outputPath, drawText); + await CreateThumbCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false); return true; } @@ -174,15 +174,15 @@ namespace MediaBrowser.Server.Implementations.Photos { if (item is UserView) { - CreateSquareCollage(item, itemsWithImages, outputPath, drawText); + await CreateSquareCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false); } else if (item is PhotoAlbum || item is Playlist) { - CreateSquareCollage(item, itemsWithImages, outputPath, drawText); + await CreateSquareCollage(item, itemsWithImages, outputPath, drawText).ConfigureAwait(false); } else { - CreatePosterCollage(item, itemsWithImages, outputPath); + await CreatePosterCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); } return true; @@ -234,7 +234,7 @@ namespace MediaBrowser.Server.Implementations.Photos protected virtual List GetFinalItems(List items, int limit) { // Rotate the images once every x days - var random = DateTime.Now.DayOfYear % 5; + var random = DateTime.Now.DayOfYear % 7; return items .OrderBy(i => (random + "" + items.IndexOf(i)).GetMD5()) diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index 4a4d90d14f..24dc2cc1d2 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -216,7 +216,7 @@ namespace MediaBrowser.Server.Implementations.UserViews return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty); } - protected override bool CreateImage(IHasImages item, List itemsWithImages, string outputPath, ImageType imageType, int imageIndex) + protected override async Task CreateImage(IHasImages item, List itemsWithImages, string outputPath, ImageType imageType, int imageIndex) { var view = (UserView)item; if (imageType == ImageType.Primary && IsUsingCollectionStrip(view)) @@ -226,11 +226,11 @@ namespace MediaBrowser.Server.Implementations.UserViews return false; } - CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540, false, item.Name); + await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540, false, item.Name).ConfigureAwait(false); return true; } - return base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex); + return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); } protected override IEnumerable GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable items) From db66b73a4f500230dd0ed4f5b93d02c6c6916973 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 23 Apr 2015 22:15:29 -0400 Subject: [PATCH 05/20] updated ImageMagickSharp --- Emby.Drawing/Emby.Drawing.csproj | 2 +- .../ImageMagick/ImageMagickEncoder.cs | 1 + Emby.Drawing/packages.config | 2 +- MediaBrowser.Api/StartupWizardService.cs | 1 + .../Configuration/BaseConfigurationManager.cs | 19 ++++++++++-- .../BaseApplicationConfiguration.cs | 6 ++++ .../Configuration/ServerConfiguration.cs | 2 -- .../ServerConfigurationManager.cs | 21 ++++++++++--- .../Sync/CloudSyncProfile.cs | 18 +++++------ .../ApplicationHost.cs | 5 +--- .../MediaBrowser.Server.Startup.Common.csproj | 1 - .../Migrations/MigrateTranscodingPath.cs | 30 ------------------- .../MediaBrowser.ServerApplication.csproj | 5 ++-- .../packages.config | 2 +- 14 files changed, 56 insertions(+), 59 deletions(-) delete mode 100644 MediaBrowser.Server.Startup.Common/Migrations/MigrateTranscodingPath.cs diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index f278e1e296..b286885a55 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -34,7 +34,7 @@ False - ..\packages\ImageMagickSharp.1.0.0.15\lib\net45\ImageMagickSharp.dll + ..\packages\ImageMagickSharp.1.0.0.16\lib\net45\ImageMagickSharp.dll diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index 3d6cdd03dd..380c56059d 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -63,6 +63,7 @@ namespace Emby.Drawing.ImageMagick { _logger.Info("ImageMagick version: " + Wand.VersionString); TestWebp(); + Wand.SetMagickThreadCount(1); } private bool _webpAvailable = true; diff --git a/Emby.Drawing/packages.config b/Emby.Drawing/packages.config index 35c98e592f..acbd2ee3ac 100644 --- a/Emby.Drawing/packages.config +++ b/Emby.Drawing/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 4655f2c6f9..6ee8d36035 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -66,6 +66,7 @@ namespace MediaBrowser.Api _config.Configuration.EnableStandaloneMetadata = true; _config.Configuration.EnableLibraryMetadataSubFolder = true; _config.Configuration.EnableUserSpecificUserViews = true; + _config.Configuration.EnableCustomPathSubFolders = true; _config.SaveConfiguration(); } diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs index c53947e443..1b9146644a 100644 --- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs +++ b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs @@ -164,9 +164,22 @@ namespace MediaBrowser.Common.Implementations.Configuration /// private void UpdateCachePath() { - ((BaseApplicationPaths)CommonApplicationPaths).CachePath = string.IsNullOrEmpty(CommonConfiguration.CachePath) ? - null : - CommonConfiguration.CachePath; + string cachePath; + + if (string.IsNullOrWhiteSpace(CommonConfiguration.CachePath)) + { + cachePath = null; + } + else if (CommonConfiguration.EnableCustomPathSubFolders) + { + cachePath = Path.Combine(CommonConfiguration.CachePath, "cache"); + } + else + { + cachePath = CommonConfiguration.CachePath; + } + + ((BaseApplicationPaths)CommonApplicationPaths).CachePath = cachePath; } /// diff --git a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs index 19620890e7..ca9db0bf08 100644 --- a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs +++ b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs @@ -50,6 +50,12 @@ namespace MediaBrowser.Model.Configuration /// The cache path. public string CachePath { get; set; } + /// + /// Gets or sets a value indicating whether [enable custom path sub folders]. + /// + /// true if [enable custom path sub folders]; otherwise, false. + public bool EnableCustomPathSubFolders { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index ac9bd6b08f..8a3a2a3e43 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -185,8 +185,6 @@ namespace MediaBrowser.Model.Configuration public MetadataOptions[] MetadataOptions { get; set; } - public string TranscodingTempPath { get; set; } - public bool EnableAutomaticRestart { get; set; } public bool EnableRealtimeMonitor { get; set; } diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs index bb9e9057a3..bf199503be 100644 --- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -101,9 +101,22 @@ namespace MediaBrowser.Server.Implementations.Configuration /// private void UpdateMetadataPath() { - ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrEmpty(Configuration.MetadataPath) ? - GetInternalMetadataPath() : - Configuration.MetadataPath; + string metadataPath; + + if (string.IsNullOrWhiteSpace(Configuration.MetadataPath)) + { + metadataPath = GetInternalMetadataPath(); + } + else if (Configuration.EnableCustomPathSubFolders) + { + metadataPath = Path.Combine(Configuration.MetadataPath, "metadata"); + } + else + { + metadataPath = Configuration.MetadataPath; + } + + ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = metadataPath; if (Configuration.MergeMetadataAndImagesByName) { @@ -130,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.Configuration ((ServerApplicationPaths)ApplicationPaths).TranscodingTempPath = string.IsNullOrEmpty(encodingConfig.TranscodingTempPath) ? null : - encodingConfig.TranscodingTempPath; + Path.Combine(encodingConfig.TranscodingTempPath, "transcoding-temp"); } protected override void OnNamedConfigurationUpdated(string key, object configuration) diff --git a/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs b/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs index 992f1d16c0..0bc527ed56 100644 --- a/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs +++ b/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs @@ -1,5 +1,5 @@ -using System.Collections.Generic; -using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Dlna; +using System.Collections.Generic; namespace MediaBrowser.Server.Implementations.Sync { @@ -31,13 +31,13 @@ namespace MediaBrowser.Server.Implementations.Sync DirectPlayProfiles = new[] { - new DirectPlayProfile - { - Container = "mkv", - VideoCodec = "h264,mpeg4", - AudioCodec = mkvAudio, - Type = DlnaProfileType.Video - }, + //new DirectPlayProfile + //{ + // Container = "mkv", + // VideoCodec = "h264,mpeg4", + // AudioCodec = mkvAudio, + // Type = DlnaProfileType.Video + //}, new DirectPlayProfile { Container = "mp4,mov,m4v", diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 0579967394..1a20f7431c 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -357,10 +357,7 @@ namespace MediaBrowser.Server.Startup.Common private void PerformPostInitMigrations() { - var migrations = new List - { - new MigrateTranscodingPath(ServerConfigurationManager) - }; + var migrations = new List(); foreach (var task in migrations) { diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index fb49692b54..4653e6ac77 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -66,7 +66,6 @@ - diff --git a/MediaBrowser.Server.Startup.Common/Migrations/MigrateTranscodingPath.cs b/MediaBrowser.Server.Startup.Common/Migrations/MigrateTranscodingPath.cs deleted file mode 100644 index 88f60841de..0000000000 --- a/MediaBrowser.Server.Startup.Common/Migrations/MigrateTranscodingPath.cs +++ /dev/null @@ -1,30 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Model.Configuration; - -namespace MediaBrowser.Server.Startup.Common.Migrations -{ - public class MigrateTranscodingPath : IVersionMigration - { - private readonly IServerConfigurationManager _config; - - public MigrateTranscodingPath(IServerConfigurationManager config) - { - _config = config; - } - - public void Run() - { - if (!string.IsNullOrWhiteSpace(_config.Configuration.TranscodingTempPath)) - { - var newConfig = _config.GetConfiguration("encoding"); - - newConfig.TranscodingTempPath = _config.Configuration.TranscodingTempPath; - _config.SaveConfiguration("encoding", newConfig); - - _config.Configuration.TranscodingTempPath = null; - _config.SaveConfiguration(); - } - } - } -} diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 5c4a15d70a..7e150248e3 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -60,9 +60,8 @@ true - - False - ..\packages\ImageMagickSharp.1.0.0.15\lib\net45\ImageMagickSharp.dll + + ..\packages\ImageMagickSharp.1.0.0.16\lib\net45\ImageMagickSharp.dll ..\packages\MediaBrowser.IsoMounting.3.0.69\lib\net45\MediaBrowser.IsoMounter.dll diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index 6c69a853d6..5007cf8af3 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file From 4d57e9b63e24abed41ba38ab82eb50c21a6938fe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 24 Apr 2015 16:06:37 -0400 Subject: [PATCH 06/20] dlna fix for media monkey --- .../Playback/BaseStreamingService.cs | 4 +++ .../ContentDirectory/ControlHandler.cs | 11 ++++++++ MediaBrowser.Model/Dlna/StreamInfo.cs | 5 ++++ .../Manager/MetadataService.cs | 25 ++++++++----------- .../Localization/Server/server.json | 2 +- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 923af3816a..dc085dab94 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1522,6 +1522,10 @@ namespace MediaBrowser.Api.Playback { request.LiveStreamId = val; } + else if (i == 24) + { + // Duplicating ItemId because of MediaMonkey + } } } diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 3d7ae8cc4d..246c234625 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -638,6 +638,17 @@ namespace MediaBrowser.Dlna.ContentDirectory Guid itemId; StubType? stubType = null; + // After using PlayTo, MediaMonkey sends a request to the server trying to get item info + const string paramsSrch = "Params="; + var paramsIndex = id.IndexOf(paramsSrch, StringComparison.OrdinalIgnoreCase); + if (paramsIndex != -1) + { + id = id.Substring(paramsIndex + paramsSrch.Length); + + var parts = id.Split(';'); + id = parts[24]; + } + if (id.StartsWith("folder_", StringComparison.OrdinalIgnoreCase)) { stubType = StubType.Folder; diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index b062bc240f..645c1c7d02 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -233,6 +233,11 @@ namespace MediaBrowser.Model.Dlna string liveStreamId = item.MediaSource == null ? null : item.MediaSource.LiveStreamId; list.Add(new NameValuePair("LiveStreamId", liveStreamId ?? string.Empty)); + if (isDlna) + { + list.Add(new NameValuePair("ItemId", item.ItemId)); + } + return list; } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 334e148506..71bc9c0651 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -360,7 +360,7 @@ namespace MediaBrowser.Providers.Manager // If replacing all metadata, run internet providers first if (options.ReplaceAllMetadata) { - var remoteResult = await ExecuteRemoteProviders(item, temp, logName, id, providers.OfType>(), cancellationToken) + var remoteResult = await ExecuteRemoteProviders(temp, logName, id, providers.OfType>(), cancellationToken) .ConfigureAwait(false); refreshResult.UpdateType = refreshResult.UpdateType | remoteResult.UpdateType; @@ -372,9 +372,8 @@ namespace MediaBrowser.Providers.Manager var hasLocalMetadata = false; var userDataList = new List(); - var localProviders = providers.OfType>().ToList(); - foreach (var provider in localProviders) + foreach (var provider in providers.OfType>().ToList()) { var providerName = provider.GetType().Name; Logger.Debug("Running {0} for {1}", providerName, logName); @@ -433,7 +432,7 @@ namespace MediaBrowser.Providers.Manager // Local metadata is king - if any is found don't run remote providers if (!options.ReplaceAllMetadata && (!hasLocalMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh)) { - var remoteResult = await ExecuteRemoteProviders(item, temp, logName, id, providers.OfType>(), cancellationToken) + var remoteResult = await ExecuteRemoteProviders(temp, logName, id, providers.OfType>(), cancellationToken) .ConfigureAwait(false); refreshResult.UpdateType = refreshResult.UpdateType | remoteResult.UpdateType; @@ -447,17 +446,15 @@ namespace MediaBrowser.Providers.Manager if (providers.Any(i => !(i is ICustomMetadataProvider))) { - // If no local providers and doing a full refresh, take data from item itself - if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh && - localProviders.Count == 0 && - refreshResult.UpdateType > ItemUpdateType.None) - { - // TODO: If the new metadata from above has some blank data, this can cause old data to get filled into those empty fields - MergeData(item, temp, new List(), false, true); - } - if (refreshResult.UpdateType > ItemUpdateType.None) { + // If no local metadata, take data from item itself + if (!hasLocalMetadata) + { + // TODO: If the new metadata from above has some blank data, this can cause old data to get filled into those empty fields + MergeData(item, temp, new List(), false, true); + } + MergeData(temp, item, item.LockedFields, true, true); } } @@ -529,7 +526,7 @@ namespace MediaBrowser.Providers.Manager return new TItemType(); } - private async Task ExecuteRemoteProviders(TItemType item, TItemType temp, string logName, TIdType id, IEnumerable> providers, CancellationToken cancellationToken) + private async Task ExecuteRemoteProviders(TItemType temp, string logName, TIdType id, IEnumerable> providers, CancellationToken cancellationToken) { var refreshResult = new RefreshResult(); diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index f464dad4ba..009fc11870 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1432,7 +1432,7 @@ "MyPreferencesWelcomeMessage2": "Would you like to set your preferences now?", "ToAccessPreferencesHelp": "To access your preferences later, click your user icon in the top right header and select My Preferences.", "HeaderViewStyles": "View Styles", - "LabelSelectViewStyles": "Enable rich presentations for:", + "LabelSelectViewStyles": "Enable enhanced presentations for:", "LabelSelectViewStylesHelp": "If enabled, views will be built with metadata to offer categories such as Suggestions, Latest, Genres, and more. If disabled, they'll be displayed with simple folders.", "TabPhotos": "Photos", "TabVideos": "Videos" From 25cdbf014e16c7607605ee7287adcc953bba6211 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 24 Apr 2015 23:30:44 -0400 Subject: [PATCH 07/20] fix refFrames not being recorded --- MediaBrowser.Api/ItemRefreshService.cs | 13 ++++++++-- .../Encoder/MediaEncoder.cs | 6 +++-- .../Probing/ProbeResultNormalizer.cs | 8 +++--- MediaBrowser.Model/Dlna/StreamBuilder.cs | 26 ++++++++++++++++--- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs index 419077f212..f56fd32828 100644 --- a/MediaBrowser.Api/ItemRefreshService.cs +++ b/MediaBrowser.Api/ItemRefreshService.cs @@ -1,7 +1,9 @@ -using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Providers; using ServiceStack; +using System.Threading; namespace MediaBrowser.Api { @@ -52,7 +54,14 @@ namespace MediaBrowser.Api var options = GetRefreshOptions(request); - _providerManager.QueueRefresh(item.Id, options); + if (item is Folder) + { + _providerManager.QueueRefresh(item.Id, options); + } + else + { + _providerManager.RefreshFullItem(item, options, CancellationToken.None); + } } private MetadataRefreshOptions GetRefreshOptions(BaseRefreshRequest request) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index d076a5b6ba..a01f37f91d 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -119,7 +119,7 @@ namespace MediaBrowser.MediaEncoding.Encoder var extractKeyFrameInterval = request.ExtractKeyFrameInterval && request.Protocol == MediaProtocol.File && request.VideoType == VideoType.VideoFile; return GetMediaInfoInternal(GetInputArgument(inputFiles, request.Protocol), request.InputPath, request.Protocol, extractChapters, extractKeyFrameInterval, - GetProbeSizeArgument(inputFiles, request.Protocol), request.MediaType == DlnaProfileType.Audio, cancellationToken); + GetProbeSizeArgument(inputFiles, request.Protocol), request.MediaType == DlnaProfileType.Audio, request.VideoType, cancellationToken); } /// @@ -155,6 +155,7 @@ namespace MediaBrowser.MediaEncoding.Encoder /// 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}. /// @@ -165,6 +166,7 @@ namespace MediaBrowser.MediaEncoding.Encoder bool extractKeyFrameInterval, string probeSizeArgument, bool isAudio, + VideoType videoType, CancellationToken cancellationToken) { var args = extractChapters @@ -236,7 +238,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, isAudio, primaryPath, protocol); + var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue) { diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 267ff875a9..2ef1c0cbd4 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -25,7 +25,7 @@ namespace MediaBrowser.MediaEncoding.Probing _fileSystem = fileSystem; } - public Model.MediaInfo.MediaInfo GetMediaInfo(InternalMediaInfoResult data, bool isAudio, string path, MediaProtocol protocol) + public Model.MediaInfo.MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType videoType, bool isAudio, string path, MediaProtocol protocol) { var info = new Model.MediaInfo.MediaInfo { @@ -79,7 +79,7 @@ namespace MediaBrowser.MediaEncoding.Probing var videoStream = info.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); - if (videoStream != null) + if (videoStream != null && videoType == VideoType.VideoFile) { UpdateFromMediaInfo(info, videoStream); } @@ -863,12 +863,14 @@ namespace MediaBrowser.MediaEncoding.Probing private void UpdateFromMediaInfo(MediaSourceInfo video, MediaStream videoStream) { - if (video.VideoType == VideoType.VideoFile && video.Protocol == MediaProtocol.File) + if (video.Protocol == MediaProtocol.File) { if (videoStream != null) { try { + _logger.Debug("Running MediaInfo against {0}", video.Path); + var result = new MediaInfoLib().GetVideoInfo(video.Path); videoStream.IsCabac = result.IsCabac ?? videoStream.IsCabac; diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 30da8bb4c9..7cda57f4be 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -456,7 +456,7 @@ namespace MediaBrowser.Model.Dlna playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue); } - int audioBitrate = GetAudioBitrate(playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec); + int audioBitrate = GetAudioBitrate(playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream); playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate); int? maxBitrateSetting = options.GetMaxBitrate(); @@ -479,17 +479,35 @@ namespace MediaBrowser.Model.Dlna return playlistItem; } - private int GetAudioBitrate(int? channels, string codec) + private int GetAudioBitrate(int? channels, string outputCodec, MediaStream audioStream) { + var defaultBitrate = 128000; + if (channels.HasValue) { if (channels.Value >= 5) { - return 320000; + defaultBitrate = 320000; } } - return 128000; + int encoderAudioBitrateLimit = int.MaxValue; + + if (audioStream != null) + { + // Seeing webm encoding failures when source has 1 audio channel and 22k bitrate. + // Any attempts to transcode over 64k will fail + if (audioStream.Channels.HasValue && + audioStream.Channels.Value == 1) + { + if ((audioStream.BitRate ?? 0) < 64000) + { + encoderAudioBitrateLimit = 64000; + } + } + } + + return Math.Min(defaultBitrate, encoderAudioBitrateLimit); } private PlayMethod? GetVideoDirectPlayProfile(DeviceProfile profile, From a7b32d4ec0bd3f4b383078a9ecf2e2f20757bdc9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 25 Apr 2015 23:25:07 -0400 Subject: [PATCH 08/20] update audio transcoding bitrate --- MediaBrowser.Api/Library/LibraryService.cs | 50 +------------ MediaBrowser.Api/UserLibrary/ItemsService.cs | 12 +-- .../Entities/Audio/IHasAlbumArtist.cs | 4 - MediaBrowser.Controller/Entities/BaseItem.cs | 35 +++------ MediaBrowser.Controller/Entities/Game.cs | 5 +- .../Entities/IHasSoundtracks.cs | 29 -------- .../Entities/Movies/Movie.cs | 4 +- MediaBrowser.Controller/Entities/TV/Series.cs | 4 +- MediaBrowser.Controller/Entities/Trailer.cs | 5 +- .../MediaBrowser.Controller.csproj | 1 - MediaBrowser.Dlna/PlayTo/PlayToController.cs | 9 +-- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 1 + MediaBrowser.Dlna/PlayTo/PlaylistItem.cs | 2 - MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs | 7 +- MediaBrowser.Dlna/Ssdp/SsdpHandler.cs | 7 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 8 +- MediaBrowser.Model/Querying/ItemFields.cs | 5 -- .../Music/MusicBrainzArtistProvider.cs | 2 +- .../Dto/DtoService.cs | 12 --- .../EntryPoints/ExternalPortForwarding.cs | 2 +- .../Library/MusicManager.cs | 6 +- .../Localization/JavaScript/kk.json | 22 +++--- .../Localization/JavaScript/nl.json | 2 +- .../Localization/JavaScript/pt_BR.json | 4 +- .../Localization/JavaScript/ru.json | 74 +++++++++---------- .../Localization/Server/nl.json | 12 +-- .../Localization/Server/pt_BR.json | 2 +- .../Localization/Server/ru.json | 58 +++++++-------- .../Api/PackageCreator.cs | 2 +- 29 files changed, 130 insertions(+), 256 deletions(-) delete mode 100644 MediaBrowser.Controller/Entities/IHasSoundtracks.cs diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 4d9afa260e..f89a703406 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -591,7 +591,7 @@ namespace MediaBrowser.Api.Library ThemeSongsResult = themeSongs, ThemeVideosResult = themeVideos, - SoundtrackSongsResult = GetSoundtrackSongs(request, request.Id, request.UserId, request.InheritFromParent) + SoundtrackSongsResult = new ThemeMediaResult() }); } @@ -789,53 +789,5 @@ namespace MediaBrowser.Api.Library return ToOptimizedSerializedResultUsingCache(lookup); } - - public ThemeMediaResult GetSoundtrackSongs(GetThemeMedia request, string id, Guid? userId, bool inheritFromParent) - { - var user = userId.HasValue ? _userManager.GetUserById(userId.Value) : null; - - var item = string.IsNullOrEmpty(id) - ? (userId.HasValue - ? user.RootFolder - : _libraryManager.RootFolder) - : _libraryManager.GetItemById(id); - - var dtoOptions = GetDtoOptions(request); - - var dtos = GetSoundtrackSongIds(item, inheritFromParent) - .Select(_libraryManager.GetItemById) - .OfType() - .SelectMany(i => i.GetRecursiveChildren(a => a is Audio)) - .OrderBy(i => i.SortName) - .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); - - var items = dtos.ToArray(); - - return new ThemeMediaResult - { - Items = items, - TotalRecordCount = items.Length, - OwnerId = _dtoService.GetDtoId(item) - }; - } - - private IEnumerable GetSoundtrackSongIds(BaseItem item, bool inherit) - { - var hasSoundtracks = item as IHasSoundtracks; - - if (hasSoundtracks != null) - { - return hasSoundtracks.SoundtrackIds; - } - - if (!inherit) - { - return new List(); - } - - hasSoundtracks = item.Parents.OfType().FirstOrDefault(); - - return hasSoundtracks != null ? hasSoundtracks.SoundtrackIds : new List(); - } } } diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index a734581f58..51f88d5743 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -58,7 +58,7 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "StudioIds", Description = "Optional. If specified, results will be filtered based on studio. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string StudioIds { get; set; } - + /// /// Gets or sets the studios. /// @@ -68,7 +68,7 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "ArtistIds", Description = "Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string ArtistIds { get; set; } - + [ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Albums { get; set; } @@ -622,7 +622,7 @@ namespace MediaBrowser.Api.UserLibrary private bool ApplyAdditionalFilters(GetItems request, BaseItem i, User user, bool isPreFiltered, ILibraryManager libraryManager) { var video = i as Video; - + if (!isPreFiltered) { var mediaTypes = request.GetMediaTypes(); @@ -979,8 +979,8 @@ namespace MediaBrowser.Api.UserLibrary if (years.Length > 0 && !(i.ProductionYear.HasValue && years.Contains(i.ProductionYear.Value))) { return false; - } - + } + // Apply person filter var personIds = request.GetPersonIds(); if (personIds.Length > 0) @@ -1057,7 +1057,7 @@ namespace MediaBrowser.Api.UserLibrary // Artists if (!string.IsNullOrEmpty(request.ArtistIds)) { - var artistIds = request.ArtistIds.Split('|'); + var artistIds = request.ArtistIds.Split(new[] { '|', ',' }); var audio = i as IHasArtist; diff --git a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs b/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs index 254f90376d..a7c914664e 100644 --- a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs @@ -17,10 +17,6 @@ namespace MediaBrowser.Controller.Entities.Audio public static class HasArtistExtensions { - public static bool HasArtist(this IHasArtist hasArtist, string artist) - { - return NameExtensions.EqualsAny(hasArtist.Artists, artist); - } public static bool HasAnyArtist(this IHasArtist hasArtist, string artist) { return NameExtensions.EqualsAny(hasArtist.AllArtists, artist); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 22efd3fba7..3313f45fd1 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -491,6 +491,17 @@ namespace MediaBrowser.Controller.Entities } } + /// + /// Finds a parent of a given type + /// + /// + /// ``0. + public T FindParent() + where T : Folder + { + return Parents.OfType().FirstOrDefault(); + } + [IgnoreDataMember] public virtual BaseItem DisplayParent { @@ -1457,30 +1468,6 @@ namespace MediaBrowser.Controller.Entities return Task.FromResult(true); } - /// - /// Finds a parent of a given type - /// - /// - /// ``0. - public T FindParent() - where T : Folder - { - var parent = Parent; - - while (parent != null) - { - var result = parent as T; - if (result != null) - { - return result; - } - - parent = parent.Parent; - } - - return null; - } - /// /// Gets an image /// diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index 899e5628f1..15d2d755a8 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -8,10 +8,8 @@ using System.Linq; namespace MediaBrowser.Controller.Entities { - public class Game : BaseItem, IHasSoundtracks, IHasTrailers, IHasThemeMedia, IHasTags, IHasScreenshots, ISupportsPlaceHolders, IHasPreferredMetadataLanguage, IHasLookupInfo + public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasTags, IHasScreenshots, ISupportsPlaceHolders, IHasPreferredMetadataLanguage, IHasLookupInfo { - public List SoundtrackIds { get; set; } - public List ThemeSongIds { get; set; } public List ThemeVideoIds { get; set; } @@ -26,7 +24,6 @@ namespace MediaBrowser.Controller.Entities public Game() { MultiPartGameFiles = new List(); - SoundtrackIds = new List(); RemoteTrailers = new List(); LocalTrailerIds = new List(); RemoteTrailerIds = new List(); diff --git a/MediaBrowser.Controller/Entities/IHasSoundtracks.cs b/MediaBrowser.Controller/Entities/IHasSoundtracks.cs deleted file mode 100644 index 3ac2491fbc..0000000000 --- a/MediaBrowser.Controller/Entities/IHasSoundtracks.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace MediaBrowser.Controller.Entities -{ - /// - /// Interface IHasSoundtracks - /// - public interface IHasSoundtracks - { - /// - /// Gets or sets the soundtrack ids. - /// - /// The soundtrack ids. - List SoundtrackIds { get; set; } - - /// - /// Gets the name. - /// - /// The name. - string Name { get; } - - /// - /// Gets the identifier. - /// - /// The identifier. - Guid Id { get; } - } -} diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 4110047821..429832088f 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -14,12 +14,11 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// Class Movie /// - public class Movie : Video, IHasCriticRating, IHasSoundtracks, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle + public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle { public List SpecialFeatureIds { get; set; } public string OriginalTitle { get; set; } - public List SoundtrackIds { get; set; } public List ThemeSongIds { get; set; } public List ThemeVideoIds { get; set; } @@ -28,7 +27,6 @@ namespace MediaBrowser.Controller.Entities.Movies public Movie() { SpecialFeatureIds = new List(); - SoundtrackIds = new List(); RemoteTrailers = new List(); LocalTrailerIds = new List(); RemoteTrailerIds = new List(); diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 91014ccdad..e7a5c69ba2 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -15,10 +15,9 @@ namespace MediaBrowser.Controller.Entities.TV /// /// Class Series /// - public class Series : Folder, IHasSoundtracks, IHasTrailers, IHasDisplayOrder, IHasLookupInfo, IHasSpecialFeatures, IMetadataContainer, IHasOriginalTitle + public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo, IHasSpecialFeatures, IMetadataContainer, IHasOriginalTitle { public List SpecialFeatureIds { get; set; } - public List SoundtrackIds { get; set; } public string OriginalTitle { get; set; } public int SeasonCount { get; set; } @@ -30,7 +29,6 @@ namespace MediaBrowser.Controller.Entities.TV AirDays = new List(); SpecialFeatureIds = new List(); - SoundtrackIds = new List(); RemoteTrailers = new List(); LocalTrailerIds = new List(); RemoteTrailerIds = new List(); diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 522e6edf69..f44128e2d6 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -14,17 +14,14 @@ namespace MediaBrowser.Controller.Entities /// Class Trailer /// [Obsolete] - public class Trailer : Video, IHasCriticRating, IHasSoundtracks, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasLookupInfo + public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasLookupInfo { - public List SoundtrackIds { get; set; } - public List ProductionLocations { get; set; } public Trailer() { RemoteTrailers = new List(); Taglines = new List(); - SoundtrackIds = new List(); Keywords = new List(); ProductionLocations = new List(); } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 199f5e0d1f..64490a74f1 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -150,7 +150,6 @@ - diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index 66cdc51afe..7a1d547e32 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -310,12 +310,12 @@ namespace MediaBrowser.Dlna.PlayTo { if (isFirst && command.StartPositionTicks.HasValue) { - playlist.Add(CreatePlaylistItem(item, user, command.StartPositionTicks.Value)); + playlist.Add(CreatePlaylistItem(item, user, command.StartPositionTicks.Value, null, null, null)); isFirst = false; } else { - playlist.Add(CreatePlaylistItem(item, user, 0)); + playlist.Add(CreatePlaylistItem(item, user, 0, null, null, null)); } } @@ -456,11 +456,6 @@ namespace MediaBrowser.Dlna.PlayTo } } - private PlaylistItem CreatePlaylistItem(BaseItem item, User user, long startPostionTicks) - { - return CreatePlaylistItem(item, user, startPostionTicks, null, null, null); - } - private PlaylistItem CreatePlaylistItem(BaseItem item, User user, long startPostionTicks, string mediaSourceId, int? audioStreamIndex, int? subtitleStreamIndex) { var deviceInfo = _device.Properties; diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index 77c98f9b97..c13f61ee5e 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -85,6 +85,7 @@ namespace MediaBrowser.Dlna.PlayTo { var uri = new Uri(location); + // TODO: Cache list of non-renderers by url to avoid repeating calls var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false); if (device.RendererCommands != null) diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs index 2af9f8da91..e1f14bfa2c 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs @@ -4,8 +4,6 @@ namespace MediaBrowser.Dlna.PlayTo { public class PlaylistItem { - public int PlayState { get; set; } - public string StreamUrl { get; set; } public string Didl { get; set; } diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs index a90c6dc01e..cac1ffe7ec 100644 --- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs +++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs @@ -47,12 +47,13 @@ namespace MediaBrowser.Dlna.Ssdp if (!network.SupportsMulticast || OperationalStatus.Up != network.OperationalStatus || !network.GetIPProperties().MulticastAddresses.Any()) continue; - - var ipV4 = network.GetIPProperties().GetIPv4Properties(); + + var properties = network.GetIPProperties(); + var ipV4 = properties.GetIPv4Properties(); if (null == ipV4) continue; - var localIps = network.GetIPProperties().UnicastAddresses + var localIps = properties.UnicastAddresses .Where(i => i.Address.AddressFamily == AddressFamily.InterNetwork) .Select(i => i.Address) .ToList(); diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index 73bc4984c8..68602a381f 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -116,13 +116,14 @@ namespace MediaBrowser.Dlna.Ssdp // Seconds to delay response values["MX"] = "3"; - SendDatagram("M-SEARCH * HTTP/1.1", values, localIp); + // UDP is unreliable, so send 3 requests at a time (per Upnp spec, sec 1.1.2) + SendDatagram("M-SEARCH * HTTP/1.1", values, localIp, 1); } public void SendDatagram(string header, Dictionary values, EndPoint localAddress, - int sendCount = 1) + int sendCount) { SendDatagram(header, values, _ssdpEndp, localAddress, false, sendCount); } @@ -132,7 +133,7 @@ namespace MediaBrowser.Dlna.Ssdp EndPoint endpoint, EndPoint localAddress, bool ignoreBindFailure, - int sendCount = 1) + int sendCount) { var msg = new SsdpMessageBuilder().BuildMessage(header, values); var queued = false; diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 7cda57f4be..cecd61e79d 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -456,7 +456,7 @@ namespace MediaBrowser.Model.Dlna playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue); } - int audioBitrate = GetAudioBitrate(playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream); + int audioBitrate = GetAudioBitrate(options.GetMaxBitrate(), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream); playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate); int? maxBitrateSetting = options.GetMaxBitrate(); @@ -479,13 +479,13 @@ namespace MediaBrowser.Model.Dlna return playlistItem; } - private int GetAudioBitrate(int? channels, string outputCodec, MediaStream audioStream) + private int GetAudioBitrate(int? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream) { var defaultBitrate = 128000; - if (channels.HasValue) + if (targetAudioChannels.HasValue) { - if (channels.Value >= 5) + if (targetAudioChannels.Value >= 5 && (maxTotalBitrate ?? 0) >= 1500000) { defaultBitrate = 320000; } diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 77b3dc0ee1..0362b7aedd 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -199,11 +199,6 @@ /// The series studio /// SeriesStudio, - - /// - /// The soundtrack ids - /// - SoundtrackIds, /// /// The sort name of the item diff --git a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs index 9741b772a5..c04f805495 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs @@ -122,7 +122,7 @@ namespace MediaBrowser.Providers.Music if (singleResult != null) { musicBrainzId = singleResult.GetProviderId(MetadataProviders.MusicBrainzArtist); - result.Item.Name = singleResult.Name; + //result.Item.Name = singleResult.Name; } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index f44b7b5a84..402bd4d985 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -325,18 +325,6 @@ namespace MediaBrowser.Server.Implementations.Dto AttachBasicFields(dto, item, owner, options); - if (fields.Contains(ItemFields.SoundtrackIds)) - { - var hasSoundtracks = item as IHasSoundtracks; - - if (hasSoundtracks != null) - { - dto.SoundtrackIds = hasSoundtracks.SoundtrackIds - .Select(i => i.ToString("N")) - .ToArray(); - } - } - var playlist = item as Playlist; if (playlist != null) { diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 2106a58dee..fa05973d87 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -106,7 +106,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints else { // Seeing some blank exceptions coming through here - _logger.ErrorException("Error reported by Mono.Nat: ", ex); + //_logger.ErrorException("Error reported by Mono.Nat: ", ex); } } diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index 3a854f2fe0..1a9e982688 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Library var genres = user.RootFolder .GetRecursiveChildren(user, i => i is Audio) .Cast