aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Drawing/Emby.Drawing.csproj2
-rw-r--r--Emby.Drawing/ImageMagick/ImageMagickEncoder.cs20
-rw-r--r--Emby.Drawing/ImageProcessor.cs9
-rw-r--r--Emby.Drawing/packages.config2
-rw-r--r--MediaBrowser.Api/ConnectService.cs55
-rw-r--r--MediaBrowser.Api/Images/ImageRequest.cs5
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs1
-rw-r--r--MediaBrowser.Api/Library/FileOrganizationService.cs39
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj3
-rw-r--r--MediaBrowser.Api/PinLoginService.cs202
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs39
-rw-r--r--MediaBrowser.Api/Playback/Progressive/VideoService.cs29
-rw-r--r--MediaBrowser.Api/Playback/StreamRequest.cs3
-rw-r--r--MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs22
-rw-r--r--MediaBrowser.Api/UserService.cs17
-rw-r--r--MediaBrowser.Api/packages.config2
-rw-r--r--MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj2
-rw-r--r--MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs24
-rw-r--r--MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs25
-rw-r--r--MediaBrowser.Common.Implementations/packages.config2
-rw-r--r--MediaBrowser.Controller/Connect/IConnectManager.cs20
-rw-r--r--MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs4
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs2
-rw-r--r--MediaBrowser.Controller/Entities/IHasMediaSources.cs2
-rw-r--r--MediaBrowser.Controller/Entities/InternalItemsQuery.cs10
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs28
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs26
-rw-r--r--MediaBrowser.Controller/Entities/UserItemData.cs12
-rw-r--r--MediaBrowser.Controller/Entities/UserRootFolder.cs3
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs7
-rw-r--r--MediaBrowser.Controller/Library/ILibraryMonitor.cs7
-rw-r--r--MediaBrowser.Controller/LiveTv/ChannelInfo.cs6
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvManager.cs9
-rw-r--r--MediaBrowser.Controller/LiveTv/ITunerHost.cs3
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs6
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj2
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs1
-rw-r--r--MediaBrowser.Controller/Providers/DirectoryService.cs3
-rw-r--r--MediaBrowser.Controller/Session/ISessionManager.cs7
-rw-r--r--MediaBrowser.Controller/packages.config2
-rw-r--r--MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs33
-rw-r--r--MediaBrowser.Dlna/MediaBrowser.Dlna.csproj2
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlayToManager.cs3
-rw-r--r--MediaBrowser.Dlna/Profiles/DefaultProfile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs3
-rw-r--r--MediaBrowser.Dlna/Profiles/XboxOneProfile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Default.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml8
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Kodi.xml6
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml12
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Vlc.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml12
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml10
-rw-r--r--MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs16
-rw-r--r--MediaBrowser.Dlna/Ssdp/SsdpHandler.cs190
-rw-r--r--MediaBrowser.Dlna/packages.config2
-rw-r--r--MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj2
-rw-r--r--MediaBrowser.LocalMetadata/packages.config2
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs9
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs12
-rw-r--r--MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj2
-rw-r--r--MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs395
-rw-r--r--MediaBrowser.MediaEncoding/packages.config2
-rw-r--r--MediaBrowser.Model.Portable/Fody.targets89
-rw-r--r--MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj17
-rw-r--r--MediaBrowser.Model.Portable/packages.config4
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs9
-rw-r--r--MediaBrowser.Model/Configuration/UserConfiguration.cs8
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs1
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs5
-rw-r--r--MediaBrowser.Model/Dlna/TranscodingProfile.cs3
-rw-r--r--MediaBrowser.Model/Entities/PersonType.cs4
-rw-r--r--MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs11
-rw-r--r--MediaBrowser.Model/Fody.targets89
-rw-r--r--MediaBrowser.Model/FodyWeavers.xml2
-rw-r--r--MediaBrowser.Model/LiveTv/LiveTvOptions.cs14
-rw-r--r--MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs6
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj15
-rw-r--r--MediaBrowser.Model/MediaInfo/MediaInfo.cs15
-rw-r--r--MediaBrowser.Model/packages.config4
-rw-r--r--MediaBrowser.Providers/Folders/DefaultImageProvider.cs12
-rw-r--r--MediaBrowser.Providers/Manager/ItemImageProvider.cs11
-rw-r--r--MediaBrowser.Providers/Manager/MetadataService.cs24
-rw-r--r--MediaBrowser.Providers/MediaBrowser.Providers.csproj2
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs4
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs17
-rw-r--r--MediaBrowser.Providers/People/MovieDbPersonProvider.cs2
-rw-r--r--MediaBrowser.Providers/packages.config2
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ConnectManager.cs145
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs27
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs14
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs8
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs70
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs6
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs9
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs5
-rw-r--r--MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs23
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs23
-rw-r--r--MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs60
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs23
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs15
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs7
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs127
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs16
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs11
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs13
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs10
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs5
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs3
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs144
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs2
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs3
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs74
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs81
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs132
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs199
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs186
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj11
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs25
-rw-r--r--MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs42
-rw-r--r--MediaBrowser.Server.Implementations/Session/SessionManager.cs81
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncHelper.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs57
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncManager.cs14
-rw-r--r--MediaBrowser.Server.Implementations/packages.config6
-rw-r--r--MediaBrowser.Server.Mac/Emby.Server.Mac.csproj552
-rw-r--r--MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj2
-rw-r--r--MediaBrowser.Server.Mono/packages.config2
-rw-r--r--MediaBrowser.Server.Startup.Common/ApplicationHost.cs2
-rw-r--r--MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj2
-rw-r--r--MediaBrowser.Server.Startup.Common/packages.config2
-rw-r--r--MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj2
-rw-r--r--MediaBrowser.ServerApplication/packages.config2
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs1
-rw-r--r--MediaBrowser.WebDashboard/Api/PackageCreator.cs2
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj542
-rw-r--r--MediaBrowser.WebDashboard/packages.config2
-rw-r--r--MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj2
-rw-r--r--MediaBrowser.XbmcMetadata/packages.config2
-rw-r--r--MediaBrowser.sln7
-rw-r--r--SharedVersion.cs2
163 files changed, 2442 insertions, 2354 deletions
diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj
index 06e042d74..4ebbbfd0a 100644
--- a/Emby.Drawing/Emby.Drawing.csproj
+++ b/Emby.Drawing/Emby.Drawing.csproj
@@ -33,7 +33,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs
index b8300ac97..cb60d1123 100644
--- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs
+++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs
@@ -155,6 +155,7 @@ namespace Emby.Drawing.ImageMagick
AutoOrientImage(originalImage);
}
+ AddForegroundLayer(originalImage, options);
DrawIndicator(originalImage, width, height, options);
originalImage.CurrentImage.CompressionQuality = quality;
@@ -177,6 +178,8 @@ namespace Emby.Drawing.ImageMagick
}
wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0);
+
+ AddForegroundLayer(wand, options);
DrawIndicator(wand, width, height, options);
wand.CurrentImage.CompressionQuality = quality;
@@ -189,6 +192,23 @@ namespace Emby.Drawing.ImageMagick
SaveDelay();
}
+ private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options)
+ {
+ if (string.IsNullOrWhiteSpace(options.ForegroundLayer))
+ {
+ return;
+ }
+
+ Double opacity;
+ if (!Double.TryParse(options.ForegroundLayer, out opacity)) opacity = .4;
+
+ using (var pixel = new PixelWand("#000", opacity))
+ using (var overlay = new MagickWand(wand.CurrentImage.Width, wand.CurrentImage.Height, pixel))
+ {
+ wand.CurrentImage.CompositeImage(overlay, CompositeOperator.OverCompositeOp, 0, 0);
+ }
+ }
+
private void AutoOrientImage(MagickWand wand)
{
wand.CurrentImage.AutoOrientImage();
diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs
index e01612700..89e2649b5 100644
--- a/Emby.Drawing/ImageProcessor.cs
+++ b/Emby.Drawing/ImageProcessor.cs
@@ -234,7 +234,7 @@ namespace Emby.Drawing
var quality = options.Quality;
var outputFormat = GetOutputFormat(options.SupportedOutputFormats[0]);
- var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor);
+ var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor, options.ForegroundLayer);
var semaphore = GetLock(cacheFilePath);
@@ -473,7 +473,7 @@ namespace Emby.Drawing
/// <summary>
/// Gets the cache file path based on a set of parameters
/// </summary>
- private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor)
+ private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor, string foregroundLayer)
{
var filename = originalPath;
@@ -507,6 +507,11 @@ namespace Emby.Drawing
filename += "b=" + backgroundColor;
}
+ if (!string.IsNullOrEmpty(foregroundLayer))
+ {
+ filename += "fl=" + foregroundLayer;
+ }
+
filename += "v=" + Version;
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());
diff --git a/Emby.Drawing/packages.config b/Emby.Drawing/packages.config
index 62a241f1f..fab573efc 100644
--- a/Emby.Drawing/packages.config
+++ b/Emby.Drawing/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="ImageMagickSharp" version="1.0.0.18" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Api/ConnectService.cs b/MediaBrowser.Api/ConnectService.cs
index bdd2eeaad..4bcd33d9e 100644
--- a/MediaBrowser.Api/ConnectService.cs
+++ b/MediaBrowser.Api/ConnectService.cs
@@ -1,10 +1,8 @@
-using System;
-using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Connect;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Connect;
-using MediaBrowser.Model.Dto;
using ServiceStack;
using System.Collections.Generic;
using System.Linq;
@@ -75,28 +73,6 @@ namespace MediaBrowser.Api
public string ConnectUserId { get; set; }
}
- [Route("/Connect/Supporters", "GET")]
- [Authenticated(Roles = "Admin")]
- public class GetConnectSupporterSummary : IReturn<ConnectSupporterSummary>
- {
- }
-
- [Route("/Connect/Supporters", "DELETE")]
- [Authenticated(Roles = "Admin")]
- public class RemoveConnectSupporter : IReturnVoid
- {
- [ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
- public string Id { get; set; }
- }
-
- [Route("/Connect/Supporters", "POST")]
- [Authenticated(Roles = "Admin")]
- public class AddConnectSupporter : IReturnVoid
- {
- [ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string Id { get; set; }
- }
-
public class ConnectService : BaseApiService
{
private readonly IConnectManager _connectManager;
@@ -108,35 +84,6 @@ namespace MediaBrowser.Api
_userManager = userManager;
}
- public async Task<object> Get(GetConnectSupporterSummary request)
- {
- var result = await _connectManager.GetConnectSupporterSummary().ConfigureAwait(false);
- var existingConnectUserIds = result.Users.Select(i => i.Id).ToList();
-
- result.EligibleUsers = _userManager.Users
- .Where(i => !string.IsNullOrWhiteSpace(i.ConnectUserId))
- .Where(i => !existingConnectUserIds.Contains(i.ConnectUserId, StringComparer.OrdinalIgnoreCase))
- .OrderBy(i => i.Name)
- .Select(i => _userManager.GetUserDto(i))
- .ToList();
-
- return ToOptimizedResult(result);
- }
-
- public void Delete(RemoveConnectSupporter request)
- {
- var task = _connectManager.RemoveConnectSupporter(request.Id);
-
- Task.WaitAll(task);
- }
-
- public void Post(AddConnectSupporter request)
- {
- var task = _connectManager.AddConnectSupporter(request.Id);
-
- Task.WaitAll(task);
- }
-
public object Post(CreateConnectLink request)
{
return _connectManager.LinkUser(request.Id, request.ConnectUsername);
diff --git a/MediaBrowser.Api/Images/ImageRequest.cs b/MediaBrowser.Api/Images/ImageRequest.cs
index cdd348bb5..8b86ee7e0 100644
--- a/MediaBrowser.Api/Images/ImageRequest.cs
+++ b/MediaBrowser.Api/Images/ImageRequest.cs
@@ -66,7 +66,10 @@ namespace MediaBrowser.Api.Images
[ApiMember(Name = "BackgroundColor", Description = "Optional. Apply a background color for transparent images.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string BackgroundColor { get; set; }
-
+
+ [ApiMember(Name = "ForegroundLayer", Description = "Optional. Apply a foreground layer on top of the image.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string ForegroundLayer { get; set; }
+
public ImageRequest()
{
EnableImageEnhancers = true;
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 7122c8fc1..8d58070fd 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -624,6 +624,7 @@ namespace MediaBrowser.Api.Images
PercentPlayed = request.PercentPlayed ?? 0,
UnplayedCount = request.UnplayedCount,
BackgroundColor = request.BackgroundColor,
+ ForegroundLayer = request.ForegroundLayer,
SupportedOutputFormats = supportedFormats
};
diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs
index 1224fa957..849e9cf0d 100644
--- a/MediaBrowser.Api/Library/FileOrganizationService.cs
+++ b/MediaBrowser.Api/Library/FileOrganizationService.cs
@@ -6,6 +6,7 @@ using MediaBrowser.Model.Querying;
using ServiceStack;
using System.Threading.Tasks;
using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Api.Library
{
@@ -54,7 +55,7 @@ namespace MediaBrowser.Api.Library
public string Id { get; set; }
}
- [Route("/Library/FileOrganizations/{Id}/Episode/Organize", "POST", Summary = "Performs an organization")]
+ [Route("/Library/FileOrganizations/{Id}/Episode/Organize", "POST", Summary = "Performs organization of a tv episode")]
public class OrganizeEpisode
{
[ApiMember(Name = "Id", Description = "Result Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
@@ -74,6 +75,18 @@ namespace MediaBrowser.Api.Library
[ApiMember(Name = "RememberCorrection", Description = "Whether or not to apply the same correction to future episodes of the same series.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
public bool RememberCorrection { get; set; }
+
+ [ApiMember(Name = "NewSeriesProviderIds", Description = "A list of provider IDs identifying a new series.", IsRequired = false, DataType = "Dictionary<string, string>", ParameterType = "query", Verb = "POST")]
+ public Dictionary<string, string> NewSeriesProviderIds { get; set; }
+
+ [ApiMember(Name = "NewSeriesName", Description = "Name of a series to add.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string NewSeriesName { get; set; }
+
+ [ApiMember(Name = "NewSeriesYear", Description = "Year of a series to add.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string NewSeriesYear { get; set; }
+
+ [ApiMember(Name = "TargetFolder", Description = "Target Folder", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public string TargetFolder { get; set; }
}
[Route("/Library/FileOrganizations/SmartMatches", "GET", Summary = "Gets smart match entries")]
@@ -106,9 +119,14 @@ namespace MediaBrowser.Api.Library
{
private readonly IFileOrganizationService _iFileOrganizationService;
- public FileOrganizationService(IFileOrganizationService iFileOrganizationService)
+ /// The _json serializer
+ /// </summary>
+ private readonly IJsonSerializer _jsonSerializer;
+
+ public FileOrganizationService(IFileOrganizationService iFileOrganizationService, IJsonSerializer jsonSerializer)
{
_iFileOrganizationService = iFileOrganizationService;
+ _jsonSerializer = jsonSerializer;
}
public object Get(GetFileOrganizationActivity request)
@@ -145,6 +163,13 @@ namespace MediaBrowser.Api.Library
public void Post(OrganizeEpisode request)
{
+ var dicNewProviderIds = new Dictionary<string, string>();
+
+ if (request.NewSeriesProviderIds != null)
+ {
+ dicNewProviderIds = request.NewSeriesProviderIds;
+ }
+
var task = _iFileOrganizationService.PerformEpisodeOrganization(new EpisodeFileOrganizationRequest
{
EndingEpisodeNumber = request.EndingEpisodeNumber,
@@ -152,9 +177,17 @@ namespace MediaBrowser.Api.Library
RememberCorrection = request.RememberCorrection,
ResultId = request.Id,
SeasonNumber = request.SeasonNumber,
- SeriesId = request.SeriesId
+ SeriesId = request.SeriesId,
+ NewSeriesName = request.NewSeriesName,
+ NewSeriesYear = request.NewSeriesYear,
+ NewSeriesProviderIds = dicNewProviderIds,
+ TargetFolder = request.TargetFolder
});
+ // For async processing (close dialog early instead of waiting until the file has been copied)
+ //var tasks = new Task[] { task };
+ //Task.WaitAll(tasks, 8000);
+
Task.WaitAll(task);
}
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index f711c69e6..be79f4d74 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -47,7 +47,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="MoreLinq">
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
@@ -80,7 +80,6 @@
<Compile Include="FilterService.cs" />
<Compile Include="IHasDtoOptions.cs" />
<Compile Include="Library\ChapterService.cs" />
- <Compile Include="PinLoginService.cs" />
<Compile Include="Playback\Dash\ManifestBuilder.cs" />
<Compile Include="Playback\Dash\MpegDashService.cs" />
<Compile Include="Playback\MediaInfoService.cs" />
diff --git a/MediaBrowser.Api/PinLoginService.cs b/MediaBrowser.Api/PinLoginService.cs
deleted file mode 100644
index 8b63de10a..000000000
--- a/MediaBrowser.Api/PinLoginService.cs
+++ /dev/null
@@ -1,202 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Globalization;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Connect;
-using ServiceStack;
-
-namespace MediaBrowser.Api
-{
- [Route("/Auth/Pin", "POST", Summary = "Creates a pin request")]
- public class CreatePinRequest : IReturn<PinCreationResult>
- {
- [ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string DeviceId { get; set; }
- }
-
- [Route("/Auth/Pin", "GET", Summary = "Gets pin status")]
- public class GetPinStatusRequest : IReturn<PinStatusResult>
- {
- [ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string DeviceId { get; set; }
- [ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string Pin { get; set; }
- }
-
- [Route("/Auth/Pin/Exchange", "POST", Summary = "Exchanges a pin")]
- public class ExchangePinRequest : IReturn<PinExchangeResult>
- {
- [ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string DeviceId { get; set; }
- [ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string Pin { get; set; }
- }
-
- [Route("/Auth/Pin/Validate", "POST", Summary = "Validates a pin")]
- [Authenticated]
- public class ValidatePinRequest : IReturnVoid
- {
- [ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string Pin { get; set; }
- }
-
- public class PinLoginService : BaseApiService
- {
- private readonly ConcurrentDictionary<string, MyPinStatus> _activeRequests = new ConcurrentDictionary<string, MyPinStatus>(StringComparer.OrdinalIgnoreCase);
-
- public object Post(CreatePinRequest request)
- {
- var pin = GetNewPin();
-
- var value = new MyPinStatus
- {
- CreationTimeUtc = DateTime.UtcNow,
- IsConfirmed = false,
- IsExpired = false,
- Pin = pin,
- DeviceId = request.DeviceId
- };
-
- _activeRequests.AddOrUpdate(pin, value, (k, v) => value);
-
- return ToOptimizedResult(new PinCreationResult
- {
- DeviceId = request.DeviceId,
- IsConfirmed = false,
- IsExpired = false,
- Pin = pin
- });
- }
-
- public object Get(GetPinStatusRequest request)
- {
- MyPinStatus status;
-
- if (!_activeRequests.TryGetValue(request.Pin, out status))
- {
- throw new ResourceNotFoundException();
- }
-
- EnsureValid(request.DeviceId, status);
-
- return ToOptimizedResult(new PinStatusResult
- {
- Pin = status.Pin,
- IsConfirmed = status.IsConfirmed,
- IsExpired = status.IsExpired
- });
- }
-
- public object Post(ExchangePinRequest request)
- {
- MyPinStatus status;
-
- if (!_activeRequests.TryGetValue(request.Pin, out status))
- {
- throw new ResourceNotFoundException();
- }
-
- EnsureValid(request.DeviceId, status);
-
- if (!status.IsConfirmed)
- {
- throw new ResourceNotFoundException();
- }
-
- return ToOptimizedResult(new PinExchangeResult
- {
- // TODO: Add access token
- UserId = status.UserId
- });
- }
-
- public void Post(ValidatePinRequest request)
- {
- MyPinStatus status;
-
- if (!_activeRequests.TryGetValue(request.Pin, out status))
- {
- throw new ResourceNotFoundException();
- }
-
- EnsureValid(status);
-
- status.IsConfirmed = true;
- status.UserId = AuthorizationContext.GetAuthorizationInfo(Request).UserId;
- }
-
- private void EnsureValid(string requestedDeviceId, MyPinStatus status)
- {
- if (!string.Equals(requestedDeviceId, status.DeviceId, StringComparison.OrdinalIgnoreCase))
- {
- throw new ResourceNotFoundException();
- }
-
- EnsureValid(status);
- }
-
- private void EnsureValid(MyPinStatus status)
- {
- if ((DateTime.UtcNow - status.CreationTimeUtc).TotalMinutes > 10)
- {
- status.IsExpired = true;
- }
-
- if (status.IsExpired)
- {
- throw new ResourceNotFoundException();
- }
- }
-
- private string GetNewPin()
- {
- var pin = GetNewPinInternal();
-
- while (IsPinActive(pin))
- {
- pin = GetNewPinInternal();
- }
-
- return pin;
- }
-
- private string GetNewPinInternal()
- {
- var length = 5;
- var pin = string.Empty;
-
- while (pin.Length < length)
- {
- var digit = new Random().Next(0, 9);
- pin += digit.ToString(CultureInfo.InvariantCulture);
- }
-
- return pin;
- }
-
- private bool IsPinActive(string pin)
- {
- MyPinStatus status;
-
- if (!_activeRequests.TryGetValue(pin, out status))
- {
- return true;
- }
-
- if (status.IsExpired)
- {
- return true;
- }
-
- return false;
- }
-
- public class MyPinStatus : PinStatusResult
- {
- public DateTime CreationTimeUtc { get; set; }
- public string DeviceId { get; set; }
- public string UserId { get; set; }
- }
- }
-}
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index bae8074fd..f66363da6 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -477,7 +477,7 @@ namespace MediaBrowser.Api.Playback
var pts = string.Empty;
- if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream)
+ if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && !state.VideoRequest.CopyTimestamps)
{
var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds;
@@ -604,6 +604,10 @@ namespace MediaBrowser.Api.Playback
{
var seconds = Math.Round(TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds);
+ var setPtsParam = state.VideoRequest.CopyTimestamps
+ ? string.Empty
+ : string.Format(",setpts=PTS -{0}/TB", seconds.ToString(UsCulture));
+
if (state.SubtitleStream.IsExternal)
{
var subtitlePath = state.SubtitleStream.Path;
@@ -621,18 +625,18 @@ namespace MediaBrowser.Api.Playback
}
// TODO: Perhaps also use original_size=1920x800 ??
- return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB",
+ return string.Format("subtitles=filename='{0}'{1}{2}",
MediaEncoder.EscapeSubtitleFilterPath(subtitlePath),
charsetParam,
- seconds.ToString(UsCulture));
+ setPtsParam);
}
var mediaPath = state.MediaPath ?? string.Empty;
- return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB",
+ return string.Format("subtitles='{0}:si={1}'{2}",
MediaEncoder.EscapeSubtitleFilterPath(mediaPath),
state.InternalSubtitleStreamOffset.ToString(UsCulture),
- seconds.ToString(UsCulture));
+ setPtsParam);
}
/// <summary>
@@ -865,6 +869,15 @@ namespace MediaBrowser.Api.Playback
{
if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
{
+ if (state.VideoStream != null && state.VideoStream.Width.HasValue)
+ {
+ // This is hacky but not sure how to get the exact subtitle resolution
+ double height = state.VideoStream.Width.Value;
+ height /= 16;
+ height *= 9;
+
+ arg += string.Format(" -canvas_size {0}:{1}", state.VideoStream.Width.Value.ToString(CultureInfo.InvariantCulture), Convert.ToInt32(height).ToString(CultureInfo.InvariantCulture));
+ }
arg += " -i \"" + state.SubtitleStream.Path + "\"";
}
}
@@ -1462,6 +1475,13 @@ namespace MediaBrowser.Api.Playback
{
// Duplicating ItemId because of MediaMonkey
}
+ else if (i == 24)
+ {
+ if (videoRequest != null)
+ {
+ videoRequest.CopyTimestamps = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
+ }
+ }
}
}
@@ -2021,6 +2041,11 @@ namespace MediaBrowser.Api.Playback
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
+
+ if (state.VideoRequest != null)
+ {
+ state.VideoRequest.CopyTimestamps = transcodingProfile.CopyTimestamps;
+ }
}
}
}
@@ -2184,9 +2209,9 @@ namespace MediaBrowser.Api.Playback
if (state.VideoRequest != null)
{
- if (string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase) && state.VideoRequest.CopyTimestamps)
{
- //inputModifier += " -noaccurate_seek";
+ inputModifier += " -noaccurate_seek";
}
}
diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
index eaf65bd6b..b7e180eca 100644
--- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
@@ -36,6 +36,7 @@ namespace MediaBrowser.Api.Playback.Progressive
[Route("/Videos/{Id}/stream.wmv", "GET")]
[Route("/Videos/{Id}/stream.wtv", "GET")]
[Route("/Videos/{Id}/stream.mov", "GET")]
+ [Route("/Videos/{Id}/stream.iso", "GET")]
[Route("/Videos/{Id}/stream", "GET")]
[Route("/Videos/{Id}/stream.ts", "HEAD")]
[Route("/Videos/{Id}/stream.webm", "HEAD")]
@@ -53,6 +54,7 @@ namespace MediaBrowser.Api.Playback.Progressive
[Route("/Videos/{Id}/stream.wtv", "HEAD")]
[Route("/Videos/{Id}/stream.m2ts", "HEAD")]
[Route("/Videos/{Id}/stream.mov", "HEAD")]
+ [Route("/Videos/{Id}/stream.iso", "HEAD")]
[Route("/Videos/{Id}/stream", "HEAD")]
[Api(Description = "Gets a video stream")]
public class GetVideoStream : VideoStreamRequest
@@ -65,7 +67,8 @@ namespace MediaBrowser.Api.Playback.Progressive
/// </summary>
public class VideoService : BaseProgressiveStreamingService
{
- public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, imageProcessor, httpClient)
+ public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient)
+ : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, imageProcessor, httpClient)
{
}
@@ -137,11 +140,6 @@ namespace MediaBrowser.Api.Playback.Progressive
var isOutputMkv = string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase);
- if (state.RunTimeTicks.HasValue)
- {
- //args += " -copyts -avoid_negative_ts disabled -start_at_zero";
- }
-
if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
if (state.VideoStream != null && IsH264(state.VideoStream) &&
@@ -150,6 +148,11 @@ namespace MediaBrowser.Api.Playback.Progressive
args += " -bsf:v h264_mp4toannexb";
}
+ if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
+ {
+ args += " -copyts -avoid_negative_ts disabled -start_at_zero";
+ }
+
return args;
}
@@ -160,10 +163,22 @@ namespace MediaBrowser.Api.Playback.Progressive
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
+ var hasCopyTs = false;
// Add resolution params, if specified
if (!hasGraphicalSubs)
{
- args += GetOutputSizeParam(state, videoCodec);
+ var outputSizeParam = GetOutputSizeParam(state, videoCodec);
+ args += outputSizeParam;
+ hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
+ }
+
+ if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
+ {
+ if (!hasCopyTs)
+ {
+ args += " -copyts";
+ }
+ args += " -avoid_negative_ts disabled -start_at_zero";
}
var qualityParam = GetVideoQualityParam(state, videoCodec);
diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs
index 69f8e6e04..1135a3a54 100644
--- a/MediaBrowser.Api/Playback/StreamRequest.cs
+++ b/MediaBrowser.Api/Playback/StreamRequest.cs
@@ -187,6 +187,9 @@ namespace MediaBrowser.Api.Playback
[ApiMember(Name = "EnableAutoStreamCopy", Description = "Whether or not to allow automatic stream copy if requested values match the original source. Defaults to true.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool EnableAutoStreamCopy { get; set; }
+ [ApiMember(Name = "CopyTimestamps", Description = "Whether or not to copy timestamps when transcoding with an offset. Defaults to false.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
+ public bool CopyTimestamps { get; set; }
+
[ApiMember(Name = "Cabac", Description = "Enable if cabac encoding is required", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? Cabac { get; set; }
diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
index 949dac926..d2da2ee84 100644
--- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
+++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
@@ -6,6 +6,7 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
+using MediaBrowser.Controller.Configuration;
namespace MediaBrowser.Api.ScheduledTasks
{
@@ -90,12 +91,14 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <value>The task manager.</value>
private ITaskManager TaskManager { get; set; }
+ private readonly IServerConfigurationManager _config;
+
/// <summary>
/// Initializes a new instance of the <see cref="ScheduledTaskService" /> class.
/// </summary>
/// <param name="taskManager">The task manager.</param>
- /// <exception cref="System.ArgumentNullException">taskManager</exception>
- public ScheduledTaskService(ITaskManager taskManager)
+ /// <exception cref="ArgumentNullException">taskManager</exception>
+ public ScheduledTaskService(ITaskManager taskManager, IServerConfigurationManager config)
{
if (taskManager == null)
{
@@ -103,6 +106,7 @@ namespace MediaBrowser.Api.ScheduledTasks
}
TaskManager = taskManager;
+ _config = config;
}
/// <summary>
@@ -194,6 +198,20 @@ namespace MediaBrowser.Api.ScheduledTasks
throw new ResourceNotFoundException("Task not found");
}
+ var hasKey = task.ScheduledTask as IHasKey;
+ if (hasKey != null)
+ {
+ if (string.Equals(hasKey.Key, "SystemUpdateTask", StringComparison.OrdinalIgnoreCase))
+ {
+ // This is a hack for now just to get the update application function to work when auto-update is disabled
+ if (!_config.Configuration.EnableAutoUpdate)
+ {
+ _config.Configuration.EnableAutoUpdate = true;
+ _config.SaveConfiguration();
+ }
+ }
+ }
+
TaskManager.Execute(task);
}
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 3996a0311..a35a1c3a2 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -415,23 +415,6 @@ namespace MediaBrowser.Api
{
var auth = AuthorizationContext.GetAuthorizationInfo(Request);
- if (string.IsNullOrWhiteSpace(auth.Client))
- {
- auth.Client = "Unknown app";
- }
- if (string.IsNullOrWhiteSpace(auth.Device))
- {
- auth.Device = "Unknown device";
- }
- if (string.IsNullOrWhiteSpace(auth.Version))
- {
- auth.Version = "Unknown version";
- }
- if (string.IsNullOrWhiteSpace(auth.DeviceId))
- {
- auth.DeviceId = "Unknown device id";
- }
-
var result = await _sessionMananger.AuthenticateNewSession(new AuthenticationRequest
{
App = auth.Client,
diff --git a/MediaBrowser.Api/packages.config b/MediaBrowser.Api/packages.config
index 83890e697..ecb1109ca 100644
--- a/MediaBrowser.Api/packages.config
+++ b/MediaBrowser.Api/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="morelinq" version="1.4.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index cb3a284c1..4bee8c042 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -49,7 +49,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="MoreLinq">
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
index ff11c889a..1b5e260d7 100644
--- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
+++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
@@ -20,7 +20,7 @@ namespace MediaBrowser.Common.Implementations.Networking
Logger = logger;
}
- private volatile List<IPAddress> _localIpAddresses;
+ private List<IPAddress> _localIpAddresses;
private readonly object _localIpAddressSyncLock = new object();
/// <summary>
@@ -29,24 +29,20 @@ namespace MediaBrowser.Common.Implementations.Networking
/// <returns>IPAddress.</returns>
public IEnumerable<IPAddress> GetLocalIpAddresses()
{
- const int cacheMinutes = 3;
- var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
+ const int cacheMinutes = 5;
- if (_localIpAddresses == null || forceRefresh)
+ lock (_localIpAddressSyncLock)
{
- lock (_localIpAddressSyncLock)
- {
- forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
+ var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
- if (_localIpAddresses == null || forceRefresh)
- {
- var addresses = GetLocalIpAddressesInternal().ToList();
+ if (_localIpAddresses == null || forceRefresh)
+ {
+ var addresses = GetLocalIpAddressesInternal().ToList();
- _localIpAddresses = addresses;
- _lastRefresh = DateTime.UtcNow;
+ _localIpAddresses = addresses;
+ _lastRefresh = DateTime.UtcNow;
- return addresses;
- }
+ return addresses;
}
}
diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
index a4ccbb6f8..8d727a112 100644
--- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
+++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
@@ -103,7 +103,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
Logger = logger;
_fileSystem = fileSystem;
- ReloadTriggerEvents(true);
+ InitTriggerEvents();
}
/// <summary>
@@ -233,11 +233,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// <summary>
/// The _triggers
/// </summary>
- private volatile List<ITaskTrigger> _triggers;
- /// <summary>
- /// The _triggers sync lock
- /// </summary>
- private readonly object _triggersSyncLock = new object();
+ private List<ITaskTrigger> _triggers;
/// <summary>
/// Gets the triggers that define when the task will run
/// </summary>
@@ -247,17 +243,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
get
{
- if (_triggers == null)
- {
- lock (_triggersSyncLock)
- {
- if (_triggers == null)
- {
- _triggers = LoadTriggers();
- }
- }
- }
-
return _triggers;
}
set
@@ -303,6 +288,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
}
}
+ private void InitTriggerEvents()
+ {
+ _triggers = LoadTriggers();
+ ReloadTriggerEvents(true);
+ }
+
public void ReloadTriggerEvents()
{
ReloadTriggerEvents(false);
diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config
index 14f0f4719..814927228 100644
--- a/MediaBrowser.Common.Implementations/packages.config
+++ b/MediaBrowser.Common.Implementations/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="morelinq" version="1.4.0" targetFramework="net45" />
<package id="NLog" version="4.2.3" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
diff --git a/MediaBrowser.Controller/Connect/IConnectManager.cs b/MediaBrowser.Controller/Connect/IConnectManager.cs
index 1f7652221..e004eaccf 100644
--- a/MediaBrowser.Controller/Connect/IConnectManager.cs
+++ b/MediaBrowser.Controller/Connect/IConnectManager.cs
@@ -76,25 +76,5 @@ namespace MediaBrowser.Controller.Connect
/// <param name="token">The token.</param>
/// <returns><c>true</c> if [is authorization token valid] [the specified token]; otherwise, <c>false</c>.</returns>
bool IsAuthorizationTokenValid(string token);
-
- /// <summary>
- /// Gets the connect supporter summary.
- /// </summary>
- /// <returns>Task&lt;ConnectSupporterSummary&gt;.</returns>
- Task<ConnectSupporterSummary> GetConnectSupporterSummary();
-
- /// <summary>
- /// Removes the connect supporter.
- /// </summary>
- /// <param name="id">The identifier.</param>
- /// <returns>Task.</returns>
- Task RemoveConnectSupporter(string id);
-
- /// <summary>
- /// Adds the connect supporter.
- /// </summary>
- /// <param name="id">The identifier.</param>
- /// <returns>Task.</returns>
- Task AddConnectSupporter(string id);
}
}
diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
index 2b80b701e..3fd8d84dd 100644
--- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
+++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
@@ -39,6 +39,7 @@ namespace MediaBrowser.Controller.Drawing
public double PercentPlayed { get; set; }
public string BackgroundColor { get; set; }
+ public string ForegroundLayer { get; set; }
public bool HasDefaultOptions(string originalImagePath)
{
@@ -83,7 +84,8 @@ namespace MediaBrowser.Controller.Drawing
!AddPlayedIndicator &&
PercentPlayed.Equals(0) &&
!UnplayedCount.HasValue &&
- string.IsNullOrEmpty(BackgroundColor);
+ string.IsNullOrEmpty(BackgroundColor) &&
+ string.IsNullOrEmpty(ForegroundLayer);
}
private bool IsFormatSupported(string originalImagePath)
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index d52e2b37f..3dfbdec56 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -1359,7 +1359,7 @@ namespace MediaBrowser.Controller.Entities
{
if (!string.IsNullOrEmpty(info.Path))
{
- var itemByPath = LibraryManager.RootFolder.FindByPath(info.Path);
+ var itemByPath = LibraryManager.FindByPath(info.Path);
if (itemByPath == null)
{
diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs
index 85ce3c781..832b9f6c1 100644
--- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs
+++ b/MediaBrowser.Controller/Entities/IHasMediaSources.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace MediaBrowser.Controller.Entities
{
- public interface IHasMediaSources : IHasId
+ public interface IHasMediaSources : IHasUserData
{
/// <summary>
/// Gets the media sources.
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index 0595d0569..8b623d64e 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -45,6 +45,8 @@ namespace MediaBrowser.Controller.Entities
public string NameLessThan { get; set; }
public string NameContains { get; set; }
+ public string Path { get; set; }
+
public string Person { get; set; }
public string[] PersonIds { get; set; }
public string[] ItemIds { get; set; }
@@ -96,7 +98,7 @@ namespace MediaBrowser.Controller.Entities
public int? MinIndexNumber { get; set; }
public double? MinCriticRating { get; set; }
public double? MinCommunityRating { get; set; }
-
+
public string[] ChannelIds { get; set; }
internal List<Guid> ItemIdsFromPersonFilters { get; set; }
@@ -112,7 +114,8 @@ namespace MediaBrowser.Controller.Entities
public string[] TopParentIds { get; set; }
public LocationType[] ExcludeLocationTypes { get; set; }
-
+ public string[] PresetViews { get; set; }
+
public InternalItemsQuery()
{
BlockUnratedItems = new UnratedItem[] { };
@@ -137,6 +140,7 @@ namespace MediaBrowser.Controller.Entities
TopParentIds = new string[] { };
ExcludeTags = new string[] { };
ExcludeLocationTypes = new LocationType[] { };
+ PresetViews = new string[] { };
}
public InternalItemsQuery(User user)
@@ -153,7 +157,7 @@ namespace MediaBrowser.Controller.Entities
}
ExcludeTags = policy.BlockedTags;
-
+
User = user;
}
}
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index 93eac058d..9efa609ef 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Providers;
+using System;
+using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Users;
@@ -6,6 +7,7 @@ using MoreLinq;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
+using System.Threading.Tasks;
using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Controller.Entities.TV
@@ -127,6 +129,30 @@ namespace MediaBrowser.Controller.Entities.TV
get { return (IndexNumber ?? -1) == 0; }
}
+ public override Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
+ {
+ var user = query.User;
+
+ Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
+
+ IEnumerable<BaseItem> items;
+
+ if (query.User == null)
+ {
+ items = query.Recursive
+ ? GetRecursiveChildren(filter)
+ : Children.Where(filter);
+ }
+ else
+ {
+ items = GetEpisodes(query.User).Where(filter);
+ }
+
+ var result = PostFilterAndSort(items, query);
+
+ return Task.FromResult(result);
+ }
+
/// <summary>
/// Gets the episodes.
/// </summary>
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 420b3c313..aa07ab378 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -157,6 +157,32 @@ namespace MediaBrowser.Controller.Entities.TV
return GetSeasons(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
}
+ public override Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
+ {
+ var user = query.User;
+
+ Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
+
+ IEnumerable<BaseItem> items;
+
+ if (query.User == null)
+ {
+ items = query.Recursive
+ ? GetRecursiveChildren(filter)
+ : Children.Where(filter);
+ }
+ else
+ {
+ items = query.Recursive
+ ? GetRecursiveChildren(user, filter)
+ : GetSeasons(user).Where(filter);
+ }
+
+ var result = PostFilterAndSort(items, query);
+
+ return Task.FromResult(result);
+ }
+
public IEnumerable<Season> GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired)
{
var seasons = base.GetChildren(user, true)
diff --git a/MediaBrowser.Controller/Entities/UserItemData.cs b/MediaBrowser.Controller/Entities/UserItemData.cs
index 5f0e62537..16c37e7d3 100644
--- a/MediaBrowser.Controller/Entities/UserItemData.cs
+++ b/MediaBrowser.Controller/Entities/UserItemData.cs
@@ -78,7 +78,17 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
public bool Played { get; set; }
-
+ /// <summary>
+ /// Gets or sets the index of the audio stream.
+ /// </summary>
+ /// <value>The index of the audio stream.</value>
+ public int? AudioStreamIndex { get; set; }
+ /// <summary>
+ /// Gets or sets the index of the subtitle stream.
+ /// </summary>
+ /// <value>The index of the subtitle stream.</value>
+ public int? SubtitleStreamIndex { get; set; }
+
/// <summary>
/// This is an interpreted property to indicate likes or dislikes
/// This should never be serialized.
diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs
index b7946cb92..daf590871 100644
--- a/MediaBrowser.Controller/Entities/UserRootFolder.cs
+++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs
@@ -30,7 +30,8 @@ namespace MediaBrowser.Controller.Entities
var result = await UserViewManager.GetUserViews(new UserViewQuery
{
- UserId = query.User.Id.ToString("N")
+ UserId = query.User.Id.ToString("N"),
+ PresetViews = query.PresetViews
}, CancellationToken.None).ConfigureAwait(false);
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 1c515edd5..ff44953ef 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -57,6 +57,13 @@ namespace MediaBrowser.Controller.Library
Person GetPerson(string name);
/// <summary>
+ /// Finds the by path.
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <returns>BaseItem.</returns>
+ BaseItem FindByPath(string path);
+
+ /// <summary>
/// Gets the artist.
/// </summary>
/// <param name="name">The name.</param>
diff --git a/MediaBrowser.Controller/Library/ILibraryMonitor.cs b/MediaBrowser.Controller/Library/ILibraryMonitor.cs
index 918382f04..e965e47d6 100644
--- a/MediaBrowser.Controller/Library/ILibraryMonitor.cs
+++ b/MediaBrowser.Controller/Library/ILibraryMonitor.cs
@@ -32,5 +32,12 @@ namespace MediaBrowser.Controller.Library
/// </summary>
/// <param name="path">The path.</param>
void ReportFileSystemChanged(string path);
+
+ /// <summary>
+ /// Determines whether [is path locked] [the specified path].
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <returns><c>true</c> if [is path locked] [the specified path]; otherwise, <c>false</c>.</returns>
+ bool IsPathLocked(string path);
}
} \ No newline at end of file
diff --git a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs
index 32b8abdc5..7d8df96ed 100644
--- a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs
@@ -26,6 +26,12 @@ namespace MediaBrowser.Controller.LiveTv
public string Id { get; set; }
/// <summary>
+ /// Gets or sets the tuner host identifier.
+ /// </summary>
+ /// <value>The tuner host identifier.</value>
+ public string TunerHostId { get; set; }
+
+ /// <summary>
/// Gets or sets the type of the channel.
/// </summary>
/// <value>The type of the channel.</value>
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
index 05c7448c3..501e48a74 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Channels;
+using System;
+using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Dto;
@@ -343,11 +344,11 @@ namespace MediaBrowser.Controller.LiveTv
/// <summary>
/// Adds the information to program dto.
/// </summary>
- /// <param name="item">The item.</param>
- /// <param name="dto">The dto.</param>
+ /// <param name="programs">The programs.</param>
/// <param name="fields">The fields.</param>
/// <param name="user">The user.</param>
- void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, List<ItemFields> fields, User user = null);
+ /// <returns>Task.</returns>
+ Task AddInfoToProgramDto(List<Tuple<BaseItem,BaseItemDto>> programs, List<ItemFields> fields, User user = null);
/// <summary>
/// Saves the tuner host.
/// </summary>
diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
index 2e3a71f70..498602ddf 100644
--- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs
+++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
@@ -46,6 +46,9 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task&lt;List&lt;MediaSourceInfo&gt;&gt;.</returns>
Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
+ }
+ public interface IConfigurableTunerHost
+ {
/// <summary>
/// Validates the specified information.
/// </summary>
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs
index 46cf4dd98..5c001f288 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs
@@ -59,6 +59,12 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The clients.</value>
public List<string> Clients { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance can reset.
+ /// </summary>
+ /// <value><c>true</c> if this instance can reset; otherwise, <c>false</c>.</value>
+ public bool CanReset { get; set; }
+
public LiveTvTunerInfo()
{
Clients = new List<string>();
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 9c17c8d9b..f74d82caa 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -46,7 +46,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="Interfaces.IO">
<HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath>
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
index bb8841222..f8f4e9ec9 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
@@ -44,6 +44,7 @@ namespace MediaBrowser.Controller.MediaEncoding
public int? CpuCoreLimit { get; set; }
public bool ReadInputAtNativeFramerate { get; set; }
public SubtitleDeliveryMethod SubtitleMethod { get; set; }
+ public bool CopyTimestamps { get; set; }
/// <summary>
/// Gets a value indicating whether this instance has fixed resolution.
diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs
index 36ef6ca1f..2192ebcac 100644
--- a/MediaBrowser.Controller/Providers/DirectoryService.cs
+++ b/MediaBrowser.Controller/Providers/DirectoryService.cs
@@ -63,7 +63,8 @@ namespace MediaBrowser.Controller.Providers
try
{
// using EnumerateFileSystemInfos doesn't handle reparse points (symlinks)
- var list = _fileSystem.GetFileSystemEntries(path);
+ var list = _fileSystem.GetFileSystemEntries(path)
+ .ToList();
// Seeing dupes on some users file system for some reason
foreach (var item in list)
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index dc9612c84..fa74c5749 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -251,6 +251,13 @@ namespace MediaBrowser.Controller.Session
Task<AuthenticationResult> AuthenticateNewSession(AuthenticationRequest request);
/// <summary>
+ /// Creates the new session.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns>Task&lt;AuthenticationResult&gt;.</returns>
+ Task<AuthenticationResult> CreateNewSession(AuthenticationRequest request);
+
+ /// <summary>
/// Reports the capabilities.
/// </summary>
/// <param name="sessionId">The session identifier.</param>
diff --git a/MediaBrowser.Controller/packages.config b/MediaBrowser.Controller/packages.config
index 8439bee10..34e16d2ad 100644
--- a/MediaBrowser.Controller/packages.config
+++ b/MediaBrowser.Controller/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
<package id="morelinq" version="1.4.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
index 9071eecb2..d1a415f73 100644
--- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
+++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
@@ -453,32 +453,17 @@ namespace MediaBrowser.Dlna.ContentDirectory
sortOrders.Add(ItemSortBy.SortName);
}
- QueryResult<BaseItem> queryResult;
-
- if (folder is UserRootFolder)
- {
- var views = await _userViewManager.GetUserViews(new UserViewQuery { UserId = user.Id.ToString("N"), PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music } }, CancellationToken.None)
- .ConfigureAwait(false);
-
- queryResult = new QueryResult<BaseItem>
- {
- Items = views.Cast<BaseItem>().ToArray()
- };
- queryResult.TotalRecordCount = queryResult.Items.Length;
- }
- else
+ var queryResult = await folder.GetItems(new InternalItemsQuery
{
- queryResult = await folder.GetItems(new InternalItemsQuery
- {
- Limit = limit,
- StartIndex = startIndex,
- SortBy = sortOrders.ToArray(),
- SortOrder = sort.SortOrder,
- User = user,
- Filter = FilterUnsupportedContent
+ Limit = limit,
+ StartIndex = startIndex,
+ SortBy = sortOrders.ToArray(),
+ SortOrder = sort.SortOrder,
+ User = user,
+ Filter = FilterUnsupportedContent,
+ PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music }
- }).ConfigureAwait(false);
- }
+ }).ConfigureAwait(false);
var options = _config.GetDlnaConfiguration();
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
index 2d672ee87..78dde72c5 100644
--- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
+++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
@@ -42,7 +42,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="MoreLinq">
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
index 06697dee6..0328111c5 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
@@ -85,8 +85,6 @@ namespace MediaBrowser.Dlna.PlayTo
try
{
- var uri = new Uri(location);
-
lock (_nonRendererUrls)
{
if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10)
@@ -101,6 +99,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
+ var uri = new Uri(location);
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false);
if (device.RendererCommands == null)
diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
index 37ce0ce67..09e10cecf 100644
--- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
@@ -31,8 +31,8 @@ namespace MediaBrowser.Dlna.Profiles
MaxIconWidth = 48;
MaxIconHeight = 48;
- MaxStreamingBitrate = 10000000;
- MaxStaticBitrate = 10000000;
+ MaxStreamingBitrate = 12000000;
+ MaxStaticBitrate = 12000000;
MusicStreamingTranscodingBitrate = 128000;
MusicSyncBitrate = 128000;
diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
index e26c3c443..1b06e1d6a 100644
--- a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
@@ -119,8 +119,7 @@ namespace MediaBrowser.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp3",
- AudioCodec = "mp3",
+ Container = "mp3,flac",
Type = DlnaProfileType.Audio
},
new DirectPlayProfile
diff --git a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs
index e82f9b58c..367aa744b 100644
--- a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs
@@ -60,8 +60,8 @@ namespace MediaBrowser.Dlna.Profiles
new DirectPlayProfile
{
Container = "ts",
- VideoCodec = "h264",
- AudioCodec = "ac3",
+ VideoCodec = "h264,mpeg2video",
+ AudioCodec = "ac3,aac,mp3",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
diff --git a/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml
index 29f7f7c75..409fe95e8 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml
@@ -23,8 +23,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -41,9 +41,9 @@
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml
index 6559e8971..ad378b01c 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Default.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml
@@ -17,8 +17,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -34,9 +34,9 @@
<DirectPlayProfile container="avi,mp4" type="Video" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
index da033f86e..ea0ea8143 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
@@ -22,8 +22,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -38,9 +38,9 @@
<DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml
index d916f9984..7ce7668a1 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml
@@ -23,8 +23,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -40,8 +40,8 @@
<DirectPlayProfile container="jpeg,jpg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mpeg" type="Video" videoCodec="mpeg2video" audioCodec="mp2" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mpeg" type="Video" videoCodec="mpeg2video" audioCodec="mp2" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
index 702f4ee6c..49f0dde8c 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -44,9 +44,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml b/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml
index 4a06c3122..d3bc20545 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Kodi.xml
@@ -41,9 +41,9 @@
<DirectPlayProfile container="" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
index e2b42a77e..95aed7c1d 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
@@ -23,8 +23,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -43,9 +43,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
index 3d37a9c9e..c7dbc62f9 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
@@ -21,8 +21,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -38,9 +38,9 @@
<DirectPlayProfile container="avi,mp4,mkv,ts" type="Video" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
index 4249fd6ca..2f28f67a1 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
@@ -23,8 +23,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -44,9 +44,9 @@
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
index b468391ef..044e32eb4 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -51,9 +51,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml
index ae9fc4de4..10944c3ac 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml
@@ -17,8 +17,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -39,9 +39,9 @@
<DirectPlayProfile container="jpeg,gif,bmp,png" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
index 2355fe7a4..4dd7db809 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
@@ -23,8 +23,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -47,13 +47,13 @@
<DirectPlayProfile container="vro,vob" audioCodec="ac3,mp2,mp3" videoCodec="mpeg1video,mpeg2video" type="Video" />
<DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3,eac3" videoCodec="mpeg2video,h264,vc1" type="Video" />
<DirectPlayProfile container="asf" audioCodec="wmav2,wmavoice" videoCodec="wmv2,wmv3" type="Video" />
- <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="mp3,flac" type="Audio" />
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
index f273fcae0..5dd426a51 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
@@ -23,8 +23,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -49,9 +49,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
index 6132e19dc..ac4ce57a0 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
@@ -25,8 +25,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -48,9 +48,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="mpeg2video" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="mpeg2video" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
index fbd67262a..1f2ebc86d 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -46,9 +46,9 @@
<DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
index 3f61b930b..5dc86c32e 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -49,9 +49,9 @@
<DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
index 0774d53f9..b34828366 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -51,9 +51,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
index c052cf85e..e94b0058b 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -56,9 +56,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml
index 91cfc0db2..653702b4a 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -56,9 +56,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
index b0825c8f6..8f78626b2 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -46,9 +46,9 @@
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3,aac,mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3,aac,mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml
index 670c8a6df..d4277d155 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -46,9 +46,9 @@
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml
index 03d39350f..433db1958 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml
@@ -23,8 +23,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -41,9 +41,9 @@
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
index e17fc087b..0bbb3f2f1 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -52,9 +52,9 @@
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Photo">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
index 0724c2a83..969bcb563 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -46,9 +46,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="asf" type="Video" videoCodec="wmv2" audioCodec="wmav2" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Bytes" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="asf" type="Video" videoCodec="wmv2" audioCodec="wmav2" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Bytes" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Video" container="mp4,mov">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
index e4344f6ab..8dbbf19e9 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
@@ -24,8 +24,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -37,7 +37,7 @@
<IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<XmlRootAttributes />
<DirectPlayProfiles>
- <DirectPlayProfile container="ts" audioCodec="ac3" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3" videoCodec="h264,mpeg2video" type="Video" />
<DirectPlayProfile container="avi" audioCodec="ac3,mp3" videoCodec="mpeg4" type="Video" />
<DirectPlayProfile container="avi" audioCodec="aac" videoCodec="h264" type="Video" />
<DirectPlayProfile container="mp4,mov,mkv" audioCodec="aac,ac3" videoCodec="h264,mpeg4,mpeg2video" type="Video" />
@@ -47,9 +47,9 @@
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" videoCodec="jpeg" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" videoCodec="jpeg" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles>
<ContainerProfile type="Video" container="mp4,mov">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
index 8812118ea..b59ce5f2a 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
@@ -23,8 +23,8 @@
<MaxAlbumArtHeight>480</MaxAlbumArtHeight>
<MaxIconWidth>48</MaxIconWidth>
<MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>10000000</MaxStreamingBitrate>
- <MaxStaticBitrate>10000000</MaxStaticBitrate>
+ <MaxStreamingBitrate>12000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>12000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
<MusicSyncBitrate>128000</MusicSyncBitrate>
<XDlnaDoc>DMS-1.50</XDlnaDoc>
@@ -44,9 +44,9 @@
<DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
</DirectPlayProfiles>
<TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" />
</TranscodingProfiles>
<ContainerProfiles />
<CodecProfiles />
diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
index 4f7dffdd9..70f6d0e53 100644
--- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
+++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
@@ -127,10 +127,14 @@ namespace MediaBrowser.Dlna.Ssdp
args.EndPoint = endPoint;
args.LocalEndPoint = new IPEndPoint(localIp, 0);
- if (!_ssdpHandler.IsSelfNotification(args))
+ if (_ssdpHandler.IgnoreMessage(args, true))
{
- TryCreateDevice(args);
+ return;
}
+
+ _ssdpHandler.LogMessageReceived(args, true);
+
+ TryCreateDevice(args);
}
}
@@ -217,14 +221,6 @@ namespace MediaBrowser.Dlna.Ssdp
return;
}
- if (_config.GetDlnaConfiguration().EnableDebugLog)
- {
- var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
- var headerText = string.Join(",", headerTexts.ToArray());
-
- _logger.Debug("{0} Device message received from {1}. Headers: {2}", args.Method, args.EndPoint, headerText);
- }
-
EventHelper.FireEventIfNotNull(DeviceDiscovered, this, args, _logger);
}
diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
index 881f70165..e48471e34 100644
--- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
+++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
@@ -86,8 +86,15 @@ namespace MediaBrowser.Dlna.Ssdp
public event EventHandler<SsdpMessageEventArgs> MessageReceived;
- private async void OnMessageReceived(SsdpMessageEventArgs args)
+ private async void OnMessageReceived(SsdpMessageEventArgs args, bool isMulticast)
{
+ if (IgnoreMessage(args, isMulticast))
+ {
+ return;
+ }
+
+ LogMessageReceived(args, isMulticast);
+
var headers = args.Headers;
string st;
@@ -108,6 +115,59 @@ namespace MediaBrowser.Dlna.Ssdp
EventHelper.FireEventIfNotNull(MessageReceived, this, args, _logger);
}
+ internal void LogMessageReceived(SsdpMessageEventArgs args, bool isMulticast)
+ {
+ var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLog;
+
+ if (enableDebugLogging)
+ {
+ var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
+ var headerText = string.Join(",", headerTexts.ToArray());
+
+ var protocol = isMulticast ? "Multicast" : "Unicast";
+ var localEndPointString = args.LocalEndPoint == null ? "null" : args.LocalEndPoint.ToString();
+ _logger.Debug("{0} message received from {1} on {3}. Protocol: {4} Headers: {2}", args.Method, args.EndPoint, headerText, localEndPointString, protocol);
+ }
+ }
+
+ internal bool IgnoreMessage(SsdpMessageEventArgs args, bool isMulticast)
+ {
+ string usn;
+ if (args.Headers.TryGetValue("USN", out usn))
+ {
+ // USN=uuid:b67df29b5c379445fde78c3774ab518d::urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1
+ if (RegisteredDevices.Select(i => i.USN).Contains(usn, StringComparer.OrdinalIgnoreCase))
+ {
+ //var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
+ //var headerText = string.Join(",", headerTexts.ToArray());
+
+ //var protocol = isMulticast ? "Multicast" : "Unicast";
+ //var localEndPointString = args.LocalEndPoint == null ? "null" : args.LocalEndPoint.ToString();
+ //_logger.Debug("IGNORING {0} message received from {1} on {3}. Protocol: {4} Headers: {2}", args.Method, args.EndPoint, headerText, localEndPointString, protocol);
+
+ return true;
+ }
+ }
+
+ string serverId;
+ if (args.Headers.TryGetValue("X-EMBY-SERVERID", out serverId))
+ {
+ if (string.Equals(serverId, _appHost.SystemId, StringComparison.OrdinalIgnoreCase))
+ {
+ //var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
+ //var headerText = string.Join(",", headerTexts.ToArray());
+
+ //var protocol = isMulticast ? "Multicast" : "Unicast";
+ //var localEndPointString = args.LocalEndPoint == null ? "null" : args.LocalEndPoint.ToString();
+ //_logger.Debug("IGNORING {0} message received from {1} on {3}. Protocol: {4} Headers: {2}", args.Method, args.EndPoint, headerText, localEndPointString, protocol);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
public IEnumerable<UpnpDevice> RegisteredDevices
{
get
@@ -126,7 +186,7 @@ namespace MediaBrowser.Dlna.Ssdp
RestartSocketListener();
ReloadAliveNotifier();
- //CreateUnicastClient();
+ CreateUnicastClient();
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
@@ -146,6 +206,7 @@ namespace MediaBrowser.Dlna.Ssdp
values["HOST"] = "239.255.255.250:1900";
values["USER-AGENT"] = "UPnP/1.0 DLNADOC/1.50 Platinum/1.0.4.2";
+ values["X-EMBY-SERVERID"] = _appHost.SystemId;
values["MAN"] = "\"ssdp:discover\"";
@@ -162,7 +223,7 @@ namespace MediaBrowser.Dlna.Ssdp
// UDP is unreliable, so send 3 requests at a time (per Upnp spec, sec 1.1.2)
SendDatagram(msg, _ssdpEndp, localIp, true);
- //SendUnicastRequest(msg);
+ SendUnicastRequest(msg);
}
public async void SendDatagram(string msg,
@@ -177,7 +238,7 @@ namespace MediaBrowser.Dlna.Ssdp
{
if (i > 0)
{
- await Task.Delay(200).ConfigureAwait(false);
+ await Task.Delay(500).ConfigureAwait(false);
}
var dgram = new Datagram(endpoint, localAddress, _logger, msg, isBroadcast, enableDebugLogging);
@@ -242,8 +303,8 @@ namespace MediaBrowser.Dlna.Ssdp
var msg = new SsdpMessageBuilder().BuildMessage(header, values);
- SendDatagram(msg, endpoint, null, false, 1);
- SendDatagram(msg, endpoint, new IPEndPoint(d.Address, 0), false, 1);
+ SendDatagram(msg, endpoint, null, false, 2);
+ SendDatagram(msg, endpoint, new IPEndPoint(d.Address, 0), false, 2);
//SendDatagram(header, values, endpoint, null, true);
if (enableDebugLogging)
@@ -324,20 +385,7 @@ namespace MediaBrowser.Dlna.Ssdp
var args = SsdpHelper.ParseSsdpResponse(received);
args.EndPoint = endpoint;
- if (IsSelfNotification(args))
- {
- return;
- }
-
- if (enableDebugLogging)
- {
- var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
- var headerText = string.Join(",", headerTexts.ToArray());
-
- _logger.Debug("{0} message received from {1} on {3}. Headers: {2}", args.Method, args.EndPoint, headerText, _multicastSocket.LocalEndPoint);
- }
-
- OnMessageReceived(args);
+ OnMessageReceived(args, true);
}
catch (ObjectDisposedException)
{
@@ -357,26 +405,6 @@ namespace MediaBrowser.Dlna.Ssdp
}
}
- internal bool IsSelfNotification(SsdpMessageEventArgs args)
- {
- // Avoid responding to self search messages
- //string serverId;
- //if (args.Headers.TryGetValue("X-EMBYSERVERID", out serverId) &&
- // string.Equals(serverId, _appHost.SystemId, StringComparison.OrdinalIgnoreCase))
- //{
- // return true;
- //}
-
- string server;
- args.Headers.TryGetValue("SERVER", out server);
-
- if (string.Equals(server, _serverSignature, StringComparison.OrdinalIgnoreCase))
- {
- //return true;
- }
- return false;
- }
-
public void Dispose()
{
_config.NamedConfigurationUpdated -= _config_ConfigurationUpdated;
@@ -448,7 +476,8 @@ namespace MediaBrowser.Dlna.Ssdp
var msg = new SsdpMessageBuilder().BuildMessage(header, values);
- SendDatagram(msg, _ssdpEndp, new IPEndPoint(dev.Address, 0), true);
+ SendDatagram(msg, _ssdpEndp, new IPEndPoint(dev.Address, 0), true, 1);
+ //SendUnicastRequest(msg, 1);
}
public void RegisterNotification(string uuid, Uri descriptionUri, IPAddress address, IEnumerable<string> services)
@@ -489,14 +518,7 @@ namespace MediaBrowser.Dlna.Ssdp
_logger.ErrorException("Error creating unicast client", ex);
}
- try
- {
- UnicastSetBeginReceive();
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in UnicastSetBeginReceive", ex);
- }
+ UnicastSetBeginReceive();
}
}
@@ -522,11 +544,18 @@ namespace MediaBrowser.Dlna.Ssdp
/// </summary>
private void UnicastSetBeginReceive()
{
- var ipRxEnd = new IPEndPoint(IPAddress.Any, _unicastPort);
- var udpListener = new UdpState { EndPoint = ipRxEnd };
+ try
+ {
+ var ipRxEnd = new IPEndPoint(IPAddress.Any, _unicastPort);
+ var udpListener = new UdpState { EndPoint = ipRxEnd };
- udpListener.UdpClient = _unicastClient;
- _unicastClient.BeginReceive(UnicastReceiveCallback, udpListener);
+ udpListener.UdpClient = _unicastClient;
+ _unicastClient.BeginReceive(UnicastReceiveCallback, udpListener);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in UnicastSetBeginReceive", ex);
+ }
}
/// <summary>
@@ -540,37 +569,66 @@ namespace MediaBrowser.Dlna.Ssdp
var endpoint = ((UdpState)(ar.AsyncState)).EndPoint;
if (udpClient.Client != null)
{
- var responseBytes = udpClient.EndReceive(ar, ref endpoint);
- var args = SsdpHelper.ParseSsdpResponse(responseBytes);
+ try
+ {
+ var responseBytes = udpClient.EndReceive(ar, ref endpoint);
+ var args = SsdpHelper.ParseSsdpResponse(responseBytes);
- args.EndPoint = endpoint;
+ args.EndPoint = endpoint;
- OnMessageReceived(args);
+ OnMessageReceived(args, false);
- UnicastSetBeginReceive();
+ UnicastSetBeginReceive();
+ }
+ catch (ObjectDisposedException)
+ {
+
+ }
+ catch (SocketException)
+ {
+
+ }
}
}
- private async void SendUnicastRequest(string request)
+ private void SendUnicastRequest(string request, int sendCount = 3)
{
if (_unicastClient == null)
{
return;
}
- _logger.Debug("Sending unicast search request");
-
- byte[] req = Encoding.ASCII.GetBytes(request);
var ipSsdp = IPAddress.Parse(SSDPAddr);
var ipTxEnd = new IPEndPoint(ipSsdp, SSDPPort);
- for (var i = 0; i < 3; i++)
+ SendUnicastRequest(request, ipTxEnd, sendCount);
+ }
+
+ private async void SendUnicastRequest(string request, IPEndPoint toEndPoint, int sendCount = 3)
+ {
+ if (_unicastClient == null)
{
- if (i > 0)
+ return;
+ }
+
+ //_logger.Debug("Sending unicast request");
+
+ byte[] req = Encoding.ASCII.GetBytes(request);
+
+ try
+ {
+ for (var i = 0; i < sendCount; i++)
{
- await Task.Delay(50).ConfigureAwait(false);
+ if (i > 0)
+ {
+ await Task.Delay(50).ConfigureAwait(false);
+ }
+ _unicastClient.Send(req, req.Length, toEndPoint);
}
- _unicastClient.Send(req, req.Length, ipTxEnd);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in SendUnicastRequest", ex);
}
}
diff --git a/MediaBrowser.Dlna/packages.config b/MediaBrowser.Dlna/packages.config
index 83890e697..ecb1109ca 100644
--- a/MediaBrowser.Dlna/packages.config
+++ b/MediaBrowser.Dlna/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="morelinq" version="1.4.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
index c673c01df..0ecb1e007 100644
--- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
+++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
@@ -33,7 +33,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="Patterns.Logging">
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
diff --git a/MediaBrowser.LocalMetadata/packages.config b/MediaBrowser.LocalMetadata/packages.config
index 28556744d..0639208dd 100644
--- a/MediaBrowser.LocalMetadata/packages.config
+++ b/MediaBrowser.LocalMetadata/packages.config
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
index 4fabed850..aef206f13 100644
--- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
@@ -460,6 +460,15 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
{
+ if (state.VideoStream != null && state.VideoStream.Width.HasValue)
+ {
+ // This is hacky but not sure how to get the exact subtitle resolution
+ double height = state.VideoStream.Width.Value;
+ height /= 16;
+ height *= 9;
+
+ arg += string.Format(" -canvas_size {0}:{1}", state.VideoStream.Width.Value.ToString(CultureInfo.InvariantCulture), Convert.ToInt32(height).ToString(CultureInfo.InvariantCulture));
+ }
arg += " -i \"" + state.SubtitleStream.Path + "\"";
}
}
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
index 252386af0..c64b574a9 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
@@ -794,6 +794,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
+
+ state.Options.CopyTimestamps = transcodingProfile.CopyTimestamps;
}
}
}
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 30e50fecd..8d1b4057b 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -129,7 +129,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <param name="request">The request.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- public Task<Model.MediaInfo.MediaInfo> GetMediaInfo(MediaInfoRequest request, CancellationToken cancellationToken)
+ public Task<MediaInfo> GetMediaInfo(MediaInfoRequest request, CancellationToken cancellationToken)
{
var extractChapters = request.MediaType == DlnaProfileType.Video && request.ExtractChapters;
@@ -175,7 +175,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{MediaInfoResult}.</returns>
/// <exception cref="System.ApplicationException">ffprobe failed - streams and format are both null.</exception>
- private async Task<Model.MediaInfo.MediaInfo> GetMediaInfoInternal(string inputPath,
+ private async Task<MediaInfo> GetMediaInfoInternal(string inputPath,
string primaryPath,
MediaProtocol protocol,
bool extractChapters,
@@ -934,7 +934,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
_mediaEncoder._runningProcesses.Remove(this);
}
- process.Dispose();
+ try
+ {
+ process.Dispose();
+ }
+ catch (Exception ex)
+ {
+ }
}
private bool _disposed;
diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
index 69f6186c7..89138592a 100644
--- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
+++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
@@ -41,7 +41,7 @@
</Reference>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="DvdLib">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath>
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index 31f6af181..57c2f75cc 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -7,7 +7,10 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Text;
+using System.Xml;
using CommonIO;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
@@ -27,7 +30,7 @@ namespace MediaBrowser.MediaEncoding.Probing
public MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType videoType, bool isAudio, string path, MediaProtocol protocol)
{
- var info = new Model.MediaInfo.MediaInfo
+ var info = new MediaInfo
{
Path = path,
Protocol = protocol
@@ -56,40 +59,100 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
- if (isAudio)
- {
- SetAudioRuntimeTicks(data, info);
+ var tags = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+ var tagStreamType = isAudio ? "audio" : "video";
- var tags = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
- // tags are normally located under data.format, but we've seen some cases with ogg where they're part of the audio stream
- // so let's create a combined list of both
+ if (data.streams != null)
+ {
+ var tagStream = data.streams.FirstOrDefault(i => string.Equals(i.codec_type, tagStreamType, StringComparison.OrdinalIgnoreCase));
- if (data.streams != null)
+ if (tagStream != null && tagStream.tags != null)
{
- var audioStream = data.streams.FirstOrDefault(i => string.Equals(i.codec_type, "audio", StringComparison.OrdinalIgnoreCase));
-
- if (audioStream != null && audioStream.tags != null)
+ foreach (var pair in tagStream.tags)
{
- foreach (var pair in audioStream.tags)
- {
- tags[pair.Key] = pair.Value;
- }
+ tags[pair.Key] = pair.Value;
}
}
+ }
- if (data.format != null && data.format.tags != null)
+ if (data.format != null && data.format.tags != null)
+ {
+ foreach (var pair in data.format.tags)
{
- foreach (var pair in data.format.tags)
- {
- tags[pair.Key] = pair.Value;
- }
+ tags[pair.Key] = pair.Value;
}
+ }
+
+ FetchGenres(info, tags);
+ var shortOverview = FFProbeHelpers.GetDictionaryValue(tags, "description");
+ var overview = FFProbeHelpers.GetDictionaryValue(tags, "synopsis");
+
+ if (string.IsNullOrWhiteSpace(overview))
+ {
+ overview = shortOverview;
+ shortOverview = null;
+ }
+ if (string.IsNullOrWhiteSpace(overview))
+ {
+ overview = FFProbeHelpers.GetDictionaryValue(tags, "desc");
+ }
+
+ if (!string.IsNullOrWhiteSpace(overview))
+ {
+ info.Overview = overview;
+ }
+
+ if (!string.IsNullOrWhiteSpace(shortOverview))
+ {
+ info.ShortOverview = shortOverview;
+ }
+
+ var title = FFProbeHelpers.GetDictionaryValue(tags, "title");
+ if (!string.IsNullOrWhiteSpace(title))
+ {
+ info.Name = title;
+ }
+
+ info.ProductionYear = FFProbeHelpers.GetDictionaryNumericValue(tags, "date");
+
+ // Several different forms of retaildate
+ info.PremiereDate = FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ??
+ FFProbeHelpers.GetDictionaryDateTime(tags, "retail date") ??
+ FFProbeHelpers.GetDictionaryDateTime(tags, "retail_date") ??
+ FFProbeHelpers.GetDictionaryDateTime(tags, "date");
+
+ if (isAudio)
+ {
+ SetAudioRuntimeTicks(data, info);
+
+ // tags are normally located under data.format, but we've seen some cases with ogg where they're part of the info stream
+ // so let's create a combined list of both
SetAudioInfoFromTags(info, tags);
}
else
{
+ FetchStudios(info, tags, "copyright");
+
+ var iTunEXTC = FFProbeHelpers.GetDictionaryValue(tags, "iTunEXTC");
+ if (!string.IsNullOrWhiteSpace(iTunEXTC))
+ {
+ var parts = iTunEXTC.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ // Example
+ // mpaa|G|100|For crude humor
+ if (parts.Length == 4)
+ {
+ info.OfficialRating = parts[1];
+ info.OfficialRatingDescription = parts[3];
+ }
+ }
+
+ var itunesXml = FFProbeHelpers.GetDictionaryValue(tags, "iTunMOVI");
+ if (!string.IsNullOrWhiteSpace(itunesXml))
+ {
+ FetchFromItunesInfo(itunesXml, info);
+ }
+
if (data.format != null && !string.IsNullOrEmpty(data.format.duration))
{
info.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, _usCulture)).Ticks;
@@ -108,10 +171,223 @@ namespace MediaBrowser.MediaEncoding.Probing
return info;
}
+ private void FetchFromItunesInfo(string xml, MediaInfo info)
+ {
+ // Make things simpler and strip out the dtd
+ xml = xml.Substring(xml.IndexOf("<plist", StringComparison.OrdinalIgnoreCase));
+ xml = "<?xml version=\"1.0\"?>" + xml;
+
+ // <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>cast</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Blender Foundation</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Janus Bager Kristensen</string>\n\t\t</dict>\n\t</array>\n\t<key>directors</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Sacha Goedegebure</string>\n\t\t</dict>\n\t</array>\n\t<key>studio</key>\n\t<string>Blender Foundation</string>\n</dict>\n</plist>\n
+ using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
+ {
+ using (var streamReader = new StreamReader(stream))
+ {
+ // Use XmlReader for best performance
+ using (var reader = XmlReader.Create(streamReader))
+ {
+ reader.MoveToContent();
+
+ // Loop through each element
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "dict":
+ using (var subtree = reader.ReadSubtree())
+ {
+ ReadFromDictNode(subtree, info);
+ }
+ break;
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void ReadFromDictNode(XmlReader reader, MediaInfo info)
+ {
+ reader.MoveToContent();
+
+ string currentKey = null;
+ List<NameValuePair> pairs = new List<NameValuePair>();
+
+ // Loop through each element
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "key":
+ if (!string.IsNullOrWhiteSpace(currentKey))
+ {
+ ProcessPairs(currentKey, pairs, info);
+ }
+ currentKey = reader.ReadElementContentAsString();
+ pairs = new List<NameValuePair>();
+ break;
+ case "string":
+ var value = reader.ReadElementContentAsString();
+ if (!string.IsNullOrWhiteSpace(value))
+ {
+ pairs.Add(new NameValuePair
+ {
+ Name = value,
+ Value = value
+ });
+ }
+ break;
+ case "array":
+ if (!string.IsNullOrWhiteSpace(currentKey))
+ {
+ using (var subtree = reader.ReadSubtree())
+ {
+ pairs.AddRange(ReadValueArray(subtree));
+ }
+ }
+ break;
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
+ }
+
+ private List<NameValuePair> ReadValueArray(XmlReader reader)
+ {
+ reader.MoveToContent();
+
+ List<NameValuePair> pairs = new List<NameValuePair>();
+
+ // Loop through each element
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "dict":
+ using (var subtree = reader.ReadSubtree())
+ {
+ var dict = GetNameValuePair(subtree);
+ if (dict != null)
+ {
+ pairs.Add(dict);
+ }
+ }
+ break;
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
+
+ return pairs;
+ }
+
+ private void ProcessPairs(string key, List<NameValuePair> pairs, MediaInfo info)
+ {
+ if (string.Equals(key, "studio", StringComparison.OrdinalIgnoreCase))
+ {
+ foreach (var pair in pairs)
+ {
+ info.Studios.Add(pair.Value);
+ }
+
+ info.Studios = info.Studios
+ .Where(i => !string.IsNullOrWhiteSpace(i))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+
+ }
+ else if (string.Equals(key, "screenwriters", StringComparison.OrdinalIgnoreCase))
+ {
+ foreach (var pair in pairs)
+ {
+ info.People.Add(new BaseItemPerson
+ {
+ Name = pair.Value,
+ Type = PersonType.Writer
+ });
+ }
+ }
+ else if (string.Equals(key, "producers", StringComparison.OrdinalIgnoreCase))
+ {
+ foreach (var pair in pairs)
+ {
+ info.People.Add(new BaseItemPerson
+ {
+ Name = pair.Value,
+ Type = PersonType.Producer
+ });
+ }
+ }
+ else if (string.Equals(key, "directors", StringComparison.OrdinalIgnoreCase))
+ {
+ foreach (var pair in pairs)
+ {
+ info.People.Add(new BaseItemPerson
+ {
+ Name = pair.Value,
+ Type = PersonType.Director
+ });
+ }
+ }
+ }
+
+ private NameValuePair GetNameValuePair(XmlReader reader)
+ {
+ reader.MoveToContent();
+
+ string name = null;
+ string value = null;
+
+ // Loop through each element
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "key":
+ name = reader.ReadElementContentAsString();
+ break;
+ case "string":
+ value = reader.ReadElementContentAsString();
+ break;
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
+
+ if (string.IsNullOrWhiteSpace(name) ||
+ string.IsNullOrWhiteSpace(value))
+ {
+ return null;
+ }
+
+ return new NameValuePair
+ {
+ Name = name,
+ Value = value
+ };
+ }
+
/// <summary>
/// Converts ffprobe stream info to our MediaStream class
/// </summary>
- /// <param name="isAudio">if set to <c>true</c> [is audio].</param>
+ /// <param name="isAudio">if set to <c>true</c> [is info].</param>
/// <param name="streamInfo">The stream info.</param>
/// <param name="formatInfo">The format info.</param>
/// <returns>MediaStream.</returns>
@@ -176,7 +452,7 @@ namespace MediaBrowser.MediaEncoding.Probing
}
else if (string.Equals(streamInfo.codec_type, "video", StringComparison.OrdinalIgnoreCase))
{
- stream.Type = isAudio || string.Equals(stream.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase)
+ stream.Type = isAudio || string.Equals(stream.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase) || string.Equals(stream.Codec, "gif", StringComparison.OrdinalIgnoreCase)
? MediaStreamType.EmbeddedImage
: MediaStreamType.Video;
@@ -388,11 +664,11 @@ namespace MediaBrowser.MediaEncoding.Probing
return null;
}
- private void SetAudioRuntimeTicks(InternalMediaInfoResult result, Model.MediaInfo.MediaInfo data)
+ private void SetAudioRuntimeTicks(InternalMediaInfoResult result, MediaInfo data)
{
if (result.streams != null)
{
- // Get the first audio stream
+ // Get the first info stream
var stream = result.streams.FirstOrDefault(s => string.Equals(s.codec_type, "audio", StringComparison.OrdinalIgnoreCase));
if (stream != null)
@@ -430,16 +706,8 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
- private void SetAudioInfoFromTags(Model.MediaInfo.MediaInfo audio, Dictionary<string, string> tags)
+ private void SetAudioInfoFromTags(MediaInfo audio, Dictionary<string, string> tags)
{
- var title = FFProbeHelpers.GetDictionaryValue(tags, "title");
-
- // Only set Name if title was found in the dictionary
- if (!string.IsNullOrEmpty(title))
- {
- audio.Title = title;
- }
-
var composer = FFProbeHelpers.GetDictionaryValue(tags, "composer");
if (!string.IsNullOrWhiteSpace(composer))
{
@@ -458,6 +726,26 @@ namespace MediaBrowser.MediaEncoding.Probing
}
}
+ var lyricist = FFProbeHelpers.GetDictionaryValue(tags, "lyricist");
+
+ if (!string.IsNullOrWhiteSpace(lyricist))
+ {
+ foreach (var person in Split(lyricist, false))
+ {
+ audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Lyricist });
+ }
+ }
+ // Check for writer some music is tagged that way as alternative to composer/lyricist
+ var writer = FFProbeHelpers.GetDictionaryValue(tags, "writer");
+
+ if (!string.IsNullOrWhiteSpace(writer))
+ {
+ foreach (var person in Split(writer, false))
+ {
+ audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Writer });
+ }
+ }
+
audio.Album = FFProbeHelpers.GetDictionaryValue(tags, "album");
var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists");
@@ -511,22 +799,12 @@ namespace MediaBrowser.MediaEncoding.Probing
// Disc number
audio.ParentIndexNumber = GetDictionaryDiscValue(tags, "disc");
- audio.ProductionYear = FFProbeHelpers.GetDictionaryNumericValue(tags, "date");
-
- // Several different forms of retaildate
- audio.PremiereDate = FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ??
- FFProbeHelpers.GetDictionaryDateTime(tags, "retail date") ??
- FFProbeHelpers.GetDictionaryDateTime(tags, "retail_date") ??
- FFProbeHelpers.GetDictionaryDateTime(tags, "date");
-
// If we don't have a ProductionYear try and get it from PremiereDate
if (audio.PremiereDate.HasValue && !audio.ProductionYear.HasValue)
{
audio.ProductionYear = audio.PremiereDate.Value.ToLocalTime().Year;
}
- FetchGenres(audio, tags);
-
// There's several values in tags may or may not be present
FetchStudios(audio, tags, "organization");
FetchStudios(audio, tags, "ensemble");
@@ -655,10 +933,10 @@ namespace MediaBrowser.MediaEncoding.Probing
/// <summary>
/// Gets the studios from the tags collection
/// </summary>
- /// <param name="audio">The audio.</param>
+ /// <param name="info">The info.</param>
/// <param name="tags">The tags.</param>
/// <param name="tagName">Name of the tag.</param>
- private void FetchStudios(Model.MediaInfo.MediaInfo audio, Dictionary<string, string> tags, string tagName)
+ private void FetchStudios(MediaInfo info, Dictionary<string, string> tags, string tagName)
{
var val = FFProbeHelpers.GetDictionaryValue(tags, tagName);
@@ -669,19 +947,19 @@ namespace MediaBrowser.MediaEncoding.Probing
foreach (var studio in studios)
{
// Sometimes the artist name is listed here, account for that
- if (audio.Artists.Contains(studio, StringComparer.OrdinalIgnoreCase))
+ if (info.Artists.Contains(studio, StringComparer.OrdinalIgnoreCase))
{
continue;
}
- if (audio.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase))
+ if (info.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase))
{
continue;
}
- audio.Studios.Add(studio);
+ info.Studios.Add(studio);
}
- audio.Studios = audio.Studios
+ info.Studios = info.Studios
.Where(i => !string.IsNullOrWhiteSpace(i))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
@@ -693,7 +971,7 @@ namespace MediaBrowser.MediaEncoding.Probing
/// </summary>
/// <param name="info">The information.</param>
/// <param name="tags">The tags.</param>
- private void FetchGenres(Model.MediaInfo.MediaInfo info, Dictionary<string, string> tags)
+ private void FetchGenres(MediaInfo info, Dictionary<string, string> tags)
{
var val = FFProbeHelpers.GetDictionaryValue(tags, "genre");
@@ -764,7 +1042,7 @@ namespace MediaBrowser.MediaEncoding.Probing
private const int MaxSubtitleDescriptionExtractionLength = 100; // When extracting subtitles, the maximum length to consider (to avoid invalid filenames)
- private void FetchWtvInfo(Model.MediaInfo.MediaInfo video, InternalMediaInfoResult data)
+ private void FetchWtvInfo(MediaInfo video, InternalMediaInfoResult data)
{
if (data.format == null || data.format.tags == null)
{
@@ -775,15 +1053,16 @@ namespace MediaBrowser.MediaEncoding.Probing
if (!string.IsNullOrWhiteSpace(genres))
{
- //genres = FFProbeHelpers.GetDictionaryValue(data.format.tags, "genre");
- }
-
- if (!string.IsNullOrWhiteSpace(genres))
- {
- video.Genres = genres.Split(new[] { ';', '/', ',' }, StringSplitOptions.RemoveEmptyEntries)
+ var genreList = genres.Split(new[] { ';', '/', ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(i => !string.IsNullOrWhiteSpace(i))
.Select(i => i.Trim())
.ToList();
+
+ // If this is empty then don't overwrite genres that might have been fetched earlier
+ if (genreList.Count > 0)
+ {
+ video.Genres = genreList;
+ }
}
var officialRating = FFProbeHelpers.GetDictionaryValue(data.format.tags, "WM/ParentalRating");
diff --git a/MediaBrowser.MediaEncoding/packages.config b/MediaBrowser.MediaEncoding/packages.config
index d6a4fc90f..0a8dd0adc 100644
--- a/MediaBrowser.MediaEncoding/packages.config
+++ b/MediaBrowser.MediaEncoding/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Model.Portable/Fody.targets b/MediaBrowser.Model.Portable/Fody.targets
deleted file mode 100644
index a668a51fc..000000000
--- a/MediaBrowser.Model.Portable/Fody.targets
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Choose>
- <When Condition="$(NCrunchOriginalSolutionDir) != '' And $(NCrunchOriginalSolutionDir) != '*Undefined*'">
- <PropertyGroup>
- <FodySolutionDir>$(NCrunchOriginalSolutionDir)</FodySolutionDir>
- </PropertyGroup>
- </When>
- <When Condition="$(SolutionDir) != '' And $(SolutionDir) != '*Undefined*'">
- <PropertyGroup>
- <FodySolutionDir>$(SolutionDir)</FodySolutionDir>
- </PropertyGroup>
- </When>
- <When Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">
- <PropertyGroup>
- <FodySolutionDir>$(MSBuildProjectDirectory)\..\</FodySolutionDir>
- </PropertyGroup>
- </When>
- </Choose>
- <Choose>
- <When Condition="$(KeyOriginatorFile) != '' And $(KeyOriginatorFile) != '*Undefined*'">
- <PropertyGroup>
- <FodyKeyFilePath>$(KeyOriginatorFile)</FodyKeyFilePath>
- </PropertyGroup>
- </When>
- <When Condition="$(AssemblyOriginatorKeyFile) != '' And $(AssemblyOriginatorKeyFile) != '*Undefined*'">
- <PropertyGroup>
- <FodyKeyFilePath>$(AssemblyOriginatorKeyFile)</FodyKeyFilePath>
- </PropertyGroup>
- </When>
- <Otherwise >
- <PropertyGroup>
- <FodyKeyFilePath></FodyKeyFilePath>
- </PropertyGroup>
- </Otherwise>
- </Choose>
- <PropertyGroup>
- <IntermediateDir>$(ProjectDir)$(IntermediateOutputPath)</IntermediateDir>
- <FodyMessageImportance Condition="$(FodyMessageImportance) == '' Or $(FodyMessageImportance) == '*Undefined*'">Low</FodyMessageImportance>
- <FodySignAssembly Condition="$(FodySignAssembly) == '' Or $(FodySignAssembly) == '*Undefined*'">$(SignAssembly)</FodySignAssembly>
- <FodyPath Condition="$(FodyPath) == '' Or $(FodyPath) == '*Undefined*'">$(MSBuildThisFileDirectory)</FodyPath>
- </PropertyGroup>
- <UsingTask
- TaskName="Fody.WeavingTask"
- AssemblyFile="$(FodyPath)\Fody.dll" />
- <Target
- AfterTargets="AfterCompile"
- Name="WinFodyTarget"
- Condition=" '$(OS)' == 'Windows_NT'">
-
- <Fody.WeavingTask
- AssemblyPath="@(IntermediateAssembly)"
- IntermediateDir="$(IntermediateDir)"
- KeyFilePath="$(FodyKeyFilePath)"
- MessageImportance="$(FodyMessageImportance)"
- ProjectDirectory="$(ProjectDir)"
- SolutionDir="$(FodySolutionDir)"
- References="@(ReferencePath)"
- SignAssembly="$(FodySignAssembly)"
- ReferenceCopyLocalPaths="@(ReferenceCopyLocalPaths)"
- DefineConstants="$(DefineConstants)"
- />
- </Target>
-
- <Target
- AfterTargets="AfterBuild"
- Name="NonWinFodyTarget"
- Condition=" '$(OS)' != 'Windows_NT'">
- <Fody.WeavingTask
- AssemblyPath="$(TargetPath)"
- IntermediateDir="$(IntermediateDir)"
- KeyFilePath="$(FodyKeyFilePath)"
- MessageImportance="$(FodyMessageImportance)"
- ProjectDirectory="$(ProjectDir)"
- SolutionDir="$(FodySolutionDir)"
- References="@(ReferencePath)"
- SignAssembly="$(FodySignAssembly)"
- ReferenceCopyLocalPaths="$(ReferenceCopyLocalPaths)"
- DefineConstants="$(DefineConstants)"
- />
- </Target>
-
-
- <!--Support for ncrunch-->
- <ItemGroup>
- <None Include="$(FodyPath)\*.*" />
- </ItemGroup>
-
-</Project> \ No newline at end of file
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index cea13f86e..5dcfded6f 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -15,7 +15,6 @@
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
- <FodyPath>..\packages\Fody.1.19.1.0</FodyPath>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
@@ -58,14 +57,6 @@
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<None Include="app.config" />
- <None Include="Fody.targets" />
- <None Include="packages.config" />
- </ItemGroup>
- <ItemGroup>
- <Reference Include="PropertyChanged">
- <HintPath>..\packages\PropertyChanged.Fody.1.41.0.0\Lib\portable-net4+sl4+wp7+win8+MonoAndroid16+MonoTouch40\PropertyChanged.dll</HintPath>
- <Private>False</Private>
- </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\MediaBrowser.Model\Activity\ActivityLogEntry.cs">
@@ -1254,7 +1245,13 @@
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
- <Import Project="Fody.targets" />
+ <Import Project="..\packages\Fody.1.29.2\build\portable-net+sl+win+wpa+wp\Fody.targets" Condition="Exists('..\packages\Fody.1.29.2\build\portable-net+sl+win+wpa+wp\Fody.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\packages\Fody.1.29.2\build\portable-net+sl+win+wpa+wp\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.29.2\build\portable-net+sl+win+wpa+wp\Fody.targets'))" />
+ </Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
diff --git a/MediaBrowser.Model.Portable/packages.config b/MediaBrowser.Model.Portable/packages.config
index 1baa00e28..cd4eb36a4 100644
--- a/MediaBrowser.Model.Portable/packages.config
+++ b/MediaBrowser.Model.Portable/packages.config
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Fody" version="1.19.1.0" targetFramework="portable-win+net45+sl40+wp71" developmentDependency="true" />
- <package id="PropertyChanged.Fody" version="1.41.0.0" targetFramework="portable-net45+sl40+wp71+win" requireReinstallation="True" />
+ <package id="Fody" version="1.29.2" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
+ <package id="PropertyChanged.Fody" version="1.50.4" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 3cb543e5d..5527c1646 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -182,8 +182,6 @@ namespace MediaBrowser.Model.Configuration
public PeopleMetadataOptions PeopleMetadataOptions { get; set; }
public bool FindInternetTrailers { get; set; }
- public string[] InsecureApps9 { get; set; }
-
public bool SaveMetadataHidden { get; set; }
public NameValuePair[] ContentTypes { get; set; }
@@ -206,6 +204,8 @@ namespace MediaBrowser.Model.Configuration
public int MigrationVersion { get; set; }
+ public bool DownloadImagesInAdvance { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
/// </summary>
@@ -256,11 +256,6 @@ namespace MediaBrowser.Model.Configuration
PeopleMetadataOptions = new PeopleMetadataOptions();
- InsecureApps9 = new[]
- {
- "Windows Phone"
- };
-
MetadataOptions = new[]
{
new MetadataOptions(1, 1280) {ItemType = "Book"},
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index d59974a2e..a024eeab4 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -48,11 +48,19 @@ namespace MediaBrowser.Model.Configuration
public bool HidePlayedInLatest { get; set; }
public bool DisplayChannelsInline { get; set; }
+ public bool RememberAudioSelections { get; set; }
+ public bool RememberSubtitleSelections { get; set; }
+ public bool EnableNextEpisodeAutoPlay { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
/// </summary>
public UserConfiguration()
{
+ EnableNextEpisodeAutoPlay = true;
+ RememberAudioSelections = true;
+ RememberSubtitleSelections = true;
+
HidePlayedInLatest = true;
PlayDefaultAudioTrack = true;
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index c2713a6e7..d4ca379c0 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -425,6 +425,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',')[0];
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
+ playlistItem.CopyTimestamps = transcodingProfile.CopyTimestamps;
playlistItem.SubProtocol = transcodingProfile.Protocol;
playlistItem.AudioStreamIndex = audioStreamIndex;
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index f5c54e160..79ee1b5c5 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -32,6 +32,7 @@ namespace MediaBrowser.Model.Dlna
public string VideoProfile { get; set; }
public bool? Cabac { get; set; }
+ public bool CopyTimestamps { get; set; }
public string AudioCodec { get; set; }
public int? AudioStreamIndex { get; set; }
@@ -231,6 +232,8 @@ namespace MediaBrowser.Model.Dlna
{
list.Add(new NameValuePair("ItemId", item.ItemId));
}
+
+ list.Add(new NameValuePair("CopyTimestamps", (item.CopyTimestamps).ToString().ToLower()));
return list;
}
@@ -269,7 +272,7 @@ namespace MediaBrowser.Model.Dlna
// HLS will preserve timestamps so we can just grab the full subtitle stream
long startPositionTicks = StringHelper.EqualsIgnoreCase(SubProtocol, "hls")
? 0
- : (this.PlayMethod == PlayMethod.Transcode ? StartPositionTicks : 0);
+ : (PlayMethod == PlayMethod.Transcode && !CopyTimestamps ? StartPositionTicks : 0);
// First add the selected track
if (SubtitleStreamIndex.HasValue)
diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
index d9963eb75..e59ee6d63 100644
--- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs
+++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
@@ -29,6 +29,9 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("transcodeSeekInfo")]
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
+ [XmlAttribute("copyTimestamps")]
+ public bool CopyTimestamps { get; set; }
+
[XmlAttribute("context")]
public EncodingContext Context { get; set; }
diff --git a/MediaBrowser.Model/Entities/PersonType.cs b/MediaBrowser.Model/Entities/PersonType.cs
index bdf846095..bc274972d 100644
--- a/MediaBrowser.Model/Entities/PersonType.cs
+++ b/MediaBrowser.Model/Entities/PersonType.cs
@@ -34,5 +34,9 @@ namespace MediaBrowser.Model.Entities
/// The conductor
/// </summary>
public const string Conductor = "Conductor";
+ /// <summary>
+ /// The lyricist
+ /// </summary>
+ public const string Lyricist = "Lyricist";
}
}
diff --git a/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs b/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs
index 0b12ebc51..b20e43e54 100644
--- a/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs
+++ b/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs
@@ -1,4 +1,6 @@
-namespace MediaBrowser.Model.FileOrganization
+using System.Collections.Generic;
+
+namespace MediaBrowser.Model.FileOrganization
{
public class EpisodeFileOrganizationRequest
{
@@ -13,5 +15,12 @@
public int? EndingEpisodeNumber { get; set; }
public bool RememberCorrection { get; set; }
+ public string NewSeriesName { get; set; }
+
+ public string NewSeriesYear { get; set; }
+
+ public string TargetFolder { get; set; }
+
+ public Dictionary<string, string> NewSeriesProviderIds { get; set; }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Model/Fody.targets b/MediaBrowser.Model/Fody.targets
deleted file mode 100644
index a668a51fc..000000000
--- a/MediaBrowser.Model/Fody.targets
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Choose>
- <When Condition="$(NCrunchOriginalSolutionDir) != '' And $(NCrunchOriginalSolutionDir) != '*Undefined*'">
- <PropertyGroup>
- <FodySolutionDir>$(NCrunchOriginalSolutionDir)</FodySolutionDir>
- </PropertyGroup>
- </When>
- <When Condition="$(SolutionDir) != '' And $(SolutionDir) != '*Undefined*'">
- <PropertyGroup>
- <FodySolutionDir>$(SolutionDir)</FodySolutionDir>
- </PropertyGroup>
- </When>
- <When Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">
- <PropertyGroup>
- <FodySolutionDir>$(MSBuildProjectDirectory)\..\</FodySolutionDir>
- </PropertyGroup>
- </When>
- </Choose>
- <Choose>
- <When Condition="$(KeyOriginatorFile) != '' And $(KeyOriginatorFile) != '*Undefined*'">
- <PropertyGroup>
- <FodyKeyFilePath>$(KeyOriginatorFile)</FodyKeyFilePath>
- </PropertyGroup>
- </When>
- <When Condition="$(AssemblyOriginatorKeyFile) != '' And $(AssemblyOriginatorKeyFile) != '*Undefined*'">
- <PropertyGroup>
- <FodyKeyFilePath>$(AssemblyOriginatorKeyFile)</FodyKeyFilePath>
- </PropertyGroup>
- </When>
- <Otherwise >
- <PropertyGroup>
- <FodyKeyFilePath></FodyKeyFilePath>
- </PropertyGroup>
- </Otherwise>
- </Choose>
- <PropertyGroup>
- <IntermediateDir>$(ProjectDir)$(IntermediateOutputPath)</IntermediateDir>
- <FodyMessageImportance Condition="$(FodyMessageImportance) == '' Or $(FodyMessageImportance) == '*Undefined*'">Low</FodyMessageImportance>
- <FodySignAssembly Condition="$(FodySignAssembly) == '' Or $(FodySignAssembly) == '*Undefined*'">$(SignAssembly)</FodySignAssembly>
- <FodyPath Condition="$(FodyPath) == '' Or $(FodyPath) == '*Undefined*'">$(MSBuildThisFileDirectory)</FodyPath>
- </PropertyGroup>
- <UsingTask
- TaskName="Fody.WeavingTask"
- AssemblyFile="$(FodyPath)\Fody.dll" />
- <Target
- AfterTargets="AfterCompile"
- Name="WinFodyTarget"
- Condition=" '$(OS)' == 'Windows_NT'">
-
- <Fody.WeavingTask
- AssemblyPath="@(IntermediateAssembly)"
- IntermediateDir="$(IntermediateDir)"
- KeyFilePath="$(FodyKeyFilePath)"
- MessageImportance="$(FodyMessageImportance)"
- ProjectDirectory="$(ProjectDir)"
- SolutionDir="$(FodySolutionDir)"
- References="@(ReferencePath)"
- SignAssembly="$(FodySignAssembly)"
- ReferenceCopyLocalPaths="@(ReferenceCopyLocalPaths)"
- DefineConstants="$(DefineConstants)"
- />
- </Target>
-
- <Target
- AfterTargets="AfterBuild"
- Name="NonWinFodyTarget"
- Condition=" '$(OS)' != 'Windows_NT'">
- <Fody.WeavingTask
- AssemblyPath="$(TargetPath)"
- IntermediateDir="$(IntermediateDir)"
- KeyFilePath="$(FodyKeyFilePath)"
- MessageImportance="$(FodyMessageImportance)"
- ProjectDirectory="$(ProjectDir)"
- SolutionDir="$(FodySolutionDir)"
- References="@(ReferencePath)"
- SignAssembly="$(FodySignAssembly)"
- ReferenceCopyLocalPaths="$(ReferenceCopyLocalPaths)"
- DefineConstants="$(DefineConstants)"
- />
- </Target>
-
-
- <!--Support for ncrunch-->
- <ItemGroup>
- <None Include="$(FodyPath)\*.*" />
- </ItemGroup>
-
-</Project> \ No newline at end of file
diff --git a/MediaBrowser.Model/FodyWeavers.xml b/MediaBrowser.Model/FodyWeavers.xml
index bb0f322ee..736992810 100644
--- a/MediaBrowser.Model/FodyWeavers.xml
+++ b/MediaBrowser.Model/FodyWeavers.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Weavers>
<PropertyChanged />
</Weavers> \ No newline at end of file
diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
index 838325d68..e705102db 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
@@ -15,7 +15,7 @@ namespace MediaBrowser.Model.LiveTv
public int PrePaddingSeconds { get; set; }
public int PostPaddingSeconds { get; set; }
-
+
public LiveTvOptions()
{
EnableMovieProviders = true;
@@ -32,6 +32,8 @@ namespace MediaBrowser.Model.LiveTv
public bool ImportFavoritesOnly { get; set; }
public bool IsEnabled { get; set; }
+ public int DataVersion { get; set; }
+
public TunerHostInfo()
{
IsEnabled = true;
@@ -47,5 +49,15 @@ namespace MediaBrowser.Model.LiveTv
public string ListingsId { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
+ public string Path { get; set; }
+
+ public string[] EnabledTuners { get; set; }
+ public bool EnableAllTuners { get; set; }
+
+ public ListingsProviderInfo()
+ {
+ EnabledTuners = new string[] { };
+ EnableAllTuners = true;
+ }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs b/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs
index fcb19427b..9af96df43 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs
@@ -64,6 +64,12 @@ namespace MediaBrowser.Model.LiveTv
/// <value>The clients.</value>
public List<string> Clients { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance can reset.
+ /// </summary>
+ /// <value><c>true</c> if this instance can reset; otherwise, <c>false</c>.</value>
+ public bool CanReset { get; set; }
+
public LiveTvTunerInfoDto()
{
Clients = new List<string>();
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index a5191192c..fda240249 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -11,7 +11,6 @@
<AssemblyName>MediaBrowser.Model</AssemblyName>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
- <FodyPath>..\packages\Fody.1.19.1.0</FodyPath>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<ReleaseVersion>
</ReleaseVersion>
@@ -442,30 +441,30 @@
<Compile Include="Users\UserAction.cs" />
<Compile Include="Users\UserActionType.cs" />
<Compile Include="Users\UserPolicy.cs" />
- <None Include="Fody.targets" />
<None Include="FodyWeavers.xml" />
<None Include="MediaBrowser.Model.snk" />
- <None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
- <Reference Include="PropertyChanged">
- <HintPath>..\packages\PropertyChanged.Fody.1.41.0.0\Lib\NET35\PropertyChanged.dll</HintPath>
- <Private>False</Private>
- </Reference>
<Reference Include="System.Xml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent />
</PropertyGroup>
- <Import Project="Fody.targets" />
<PropertyGroup>
<PostBuildEvent />
</PropertyGroup>
+ <Import Project="..\packages\Fody.1.29.2\build\dotnet\Fody.targets" Condition="Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.29.2\build\dotnet\Fody.targets'))" />
+ </Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
diff --git a/MediaBrowser.Model/MediaInfo/MediaInfo.cs b/MediaBrowser.Model/MediaInfo/MediaInfo.cs
index 21f258693..de082635d 100644
--- a/MediaBrowser.Model/MediaInfo/MediaInfo.cs
+++ b/MediaBrowser.Model/MediaInfo/MediaInfo.cs
@@ -10,11 +10,6 @@ namespace MediaBrowser.Model.MediaInfo
public List<ChapterInfo> Chapters { get; set; }
/// <summary>
- /// Gets or sets the title.
- /// </summary>
- /// <value>The title.</value>
- public string Title { get; set; }
- /// <summary>
/// Gets or sets the album.
/// </summary>
/// <value>The album.</value>
@@ -47,10 +42,20 @@ namespace MediaBrowser.Model.MediaInfo
/// <value>The official rating.</value>
public string OfficialRating { get; set; }
/// <summary>
+ /// Gets or sets the official rating description.
+ /// </summary>
+ /// <value>The official rating description.</value>
+ public string OfficialRatingDescription { get; set; }
+ /// <summary>
/// Gets or sets the overview.
/// </summary>
/// <value>The overview.</value>
public string Overview { get; set; }
+ /// <summary>
+ /// Gets or sets the short overview.
+ /// </summary>
+ /// <value>The short overview.</value>
+ public string ShortOverview { get; set; }
public MediaInfo()
{
diff --git a/MediaBrowser.Model/packages.config b/MediaBrowser.Model/packages.config
index 3d7793afb..df2ddcf0f 100644
--- a/MediaBrowser.Model/packages.config
+++ b/MediaBrowser.Model/packages.config
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Fody" version="1.19.1.0" targetFramework="net45" developmentDependency="true" />
- <package id="PropertyChanged.Fody" version="1.41.0.0" targetFramework="net45" />
+ <package id="Fody" version="1.29.2" targetFramework="net45" developmentDependency="true" />
+ <package id="PropertyChanged.Fody" version="1.50.4" targetFramework="net45" developmentDependency="true" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs
index a5a2e1e72..ca543163d 100644
--- a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs
+++ b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs
@@ -25,8 +25,7 @@ namespace MediaBrowser.Providers.Folders
{
return new List<ImageType>
{
- ImageType.Primary,
- ImageType.Thumb
+ ImageType.Primary
};
}
@@ -57,13 +56,6 @@ namespace MediaBrowser.Providers.Folders
ProviderName = Name,
Url = url,
Type = ImageType.Primary
- },
-
- new RemoteImageInfo
- {
- ProviderName = Name,
- Url = url,
- Type = ImageType.Thumb
}
});
}
@@ -121,7 +113,7 @@ namespace MediaBrowser.Providers.Folders
}
if (string.Equals(viewType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
{
- return urlPrefix + "collections.jpg";
+ //return urlPrefix + "collections.jpg";
}
if (string.IsNullOrWhiteSpace(viewType))
{
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index 370187801..73e09c1e6 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -18,6 +18,7 @@ using System.Threading;
using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Providers.Manager
@@ -520,6 +521,16 @@ namespace MediaBrowser.Providers.Manager
private bool EnableImageStub(IHasImages item, ImageType type)
{
+ if (item is LiveTvProgram)
+ {
+ return true;
+ }
+
+ if (_config.Configuration.DownloadImagesInAdvance)
+ {
+ return false;
+ }
+
if (item.LocationType == LocationType.Remote || item.LocationType == LocationType.Virtual)
{
return true;
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index e18da565d..416cc51bd 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -283,12 +283,7 @@ namespace MediaBrowser.Providers.Manager
if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary))
{
- personEntity.SetImage(new ItemImageInfo
- {
- Path = person.ImageUrl,
- Type = ImageType.Primary,
- IsPlaceholder = true
- }, 0);
+ await AddPersonImage(personEntity, person.ImageUrl, cancellationToken).ConfigureAwait(false);
saveEntity = true;
updateType = updateType | ItemUpdateType.ImageUpdate;
@@ -302,6 +297,23 @@ namespace MediaBrowser.Providers.Manager
}
}
+ private async Task AddPersonImage(Person personEntity, string imageUrl, CancellationToken cancellationToken)
+ {
+ if (ServerConfigurationManager.Configuration.DownloadImagesInAdvance)
+ {
+ await ProviderManager.SaveImage(personEntity, imageUrl, null, ImageType.Primary, null, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ personEntity.SetImage(new ItemImageInfo
+ {
+ Path = imageUrl,
+ Type = ImageType.Primary,
+ IsPlaceholder = true
+ }, 0);
+ }
+ }
+
private readonly Task _cachedTask = Task.FromResult(true);
protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
{
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 24397dd5a..d316d2cd8 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -50,7 +50,7 @@
</Reference>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="DvdLib, Version=1.0.5167.21152, Culture=neutral, PublicKeyToken=7a2f3f5ec8d93575, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
index 4cf507d15..78906fa85 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
@@ -125,9 +125,9 @@ namespace MediaBrowser.Providers.MediaInfo
private async Task FetchDataFromTags(Audio audio, Model.MediaInfo.MediaInfo data)
{
// Only set Name if title was found in the dictionary
- if (!string.IsNullOrEmpty(data.Title))
+ if (!string.IsNullOrEmpty(data.Name))
{
- audio.Name = data.Title;
+ audio.Name = data.Name;
}
if (!audio.LockedFields.Contains(MetadataFields.Cast))
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
index ebbc045ab..ee05a89a8 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
@@ -383,6 +383,11 @@ namespace MediaBrowser.Providers.MediaInfo
}
}
+ if (!string.IsNullOrWhiteSpace(data.OfficialRatingDescription) || isFullRefresh)
+ {
+ video.OfficialRatingDescription = data.OfficialRatingDescription;
+ }
+
if (!video.LockedFields.Contains(MetadataFields.Genres))
{
if (video.Genres.Count == 0 || isFullRefresh)
@@ -437,6 +442,13 @@ namespace MediaBrowser.Providers.MediaInfo
video.ParentIndexNumber = data.ParentIndexNumber;
}
}
+ if (!string.IsNullOrWhiteSpace(data.Name))
+ {
+ if (string.IsNullOrWhiteSpace(video.Name) || string.Equals(video.Name, Path.GetFileNameWithoutExtension(video.Path), StringComparison.OrdinalIgnoreCase))
+ {
+ video.Name = data.Name;
+ }
+ }
// If we don't have a ProductionYear try and get it from PremiereDate
if (video.PremiereDate.HasValue && !video.ProductionYear.HasValue)
@@ -451,6 +463,11 @@ namespace MediaBrowser.Providers.MediaInfo
video.Overview = data.Overview;
}
}
+
+ if (string.IsNullOrWhiteSpace(video.ShortOverview) || isFullRefresh)
+ {
+ video.ShortOverview = data.ShortOverview;
+ }
}
private async Task FetchPeople(Video video, Model.MediaInfo.MediaInfo data, MetadataRefreshOptions options)
diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
index 5525b547f..43302dd89 100644
--- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
+++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
@@ -99,7 +99,7 @@ namespace MediaBrowser.Providers.People
var requestCount = _requestCount;
- if (requestCount >= 10)
+ if (requestCount >= 20)
{
//_logger.Debug("Throttling Tmdb people");
diff --git a/MediaBrowser.Providers/packages.config b/MediaBrowser.Providers/packages.config
index 08f8ef3b0..89172044a 100644
--- a/MediaBrowser.Providers/packages.config
+++ b/MediaBrowser.Providers/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
<package id="morelinq" version="1.4.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
index fdc7e9ee2..d7477225c 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
+++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
@@ -10,7 +10,6 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.Connect;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization;
@@ -24,7 +23,6 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
-using MediaBrowser.Common.IO;
namespace MediaBrowser.Server.Implementations.Connect
{
@@ -121,7 +119,6 @@ namespace MediaBrowser.Server.Implementations.Connect
_securityManager = securityManager;
_fileSystem = fileSystem;
- _userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated;
_config.ConfigurationUpdated += _config_ConfigurationUpdated;
LoadCachedData();
@@ -1071,90 +1068,6 @@ namespace MediaBrowser.Server.Implementations.Connect
}
}
- public async Task<ConnectSupporterSummary> GetConnectSupporterSummary()
- {
- var url = GetConnectUrl("keyAssociation");
-
- var options = new HttpRequestOptions
- {
- Url = url,
- CancellationToken = CancellationToken.None
- };
-
- var postData = new Dictionary<string, string>
- {
- {"serverId", ConnectServerId},
- {"supporterKey", _securityManager.SupporterKey}
- };
-
- options.SetPostData(postData);
-
- SetServerAccessToken(options);
- SetApplicationHeader(options);
-
- // No need to examine the response
- using (var stream = (await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)).Content)
- {
- return _json.DeserializeFromStream<ConnectSupporterSummary>(stream);
- }
- }
-
- public async Task AddConnectSupporter(string id)
- {
- var url = GetConnectUrl("keyAssociation");
-
- var options = new HttpRequestOptions
- {
- Url = url,
- CancellationToken = CancellationToken.None
- };
-
- var postData = new Dictionary<string, string>
- {
- {"serverId", ConnectServerId},
- {"supporterKey", _securityManager.SupporterKey},
- {"userId", id}
- };
-
- options.SetPostData(postData);
-
- SetServerAccessToken(options);
- SetApplicationHeader(options);
-
- // No need to examine the response
- using (var stream = (await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)).Content)
- {
- }
- }
-
- public async Task RemoveConnectSupporter(string id)
- {
- var url = GetConnectUrl("keyAssociation");
-
- var options = new HttpRequestOptions
- {
- Url = url,
- CancellationToken = CancellationToken.None
- };
-
- var postData = new Dictionary<string, string>
- {
- {"serverId", ConnectServerId},
- {"supporterKey", _securityManager.SupporterKey},
- {"userId", id}
- };
-
- options.SetPostData(postData);
-
- SetServerAccessToken(options);
- SetApplicationHeader(options);
-
- // No need to examine the response
- using (var stream = (await _httpClient.SendAsync(options, "DELETE").ConfigureAwait(false)).Content)
- {
- }
- }
-
public async Task Authenticate(string username, string passwordMd5)
{
if (string.IsNullOrWhiteSpace(username))
@@ -1186,64 +1099,6 @@ namespace MediaBrowser.Server.Implementations.Connect
}
}
- async void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs<User> e)
- {
- var user = e.Argument;
-
- await TryUploadUserPreferences(user, CancellationToken.None).ConfigureAwait(false);
- }
-
- private async Task TryUploadUserPreferences(User user, CancellationToken cancellationToken)
- {
- if (user == null)
- {
- throw new ArgumentNullException("user");
- }
-
- if (string.IsNullOrEmpty(user.ConnectUserId))
- {
- return;
- }
- if (string.IsNullOrEmpty(ConnectAccessKey))
- {
- return;
- }
-
- var url = GetConnectUrl("user/preferences");
- url += "?userId=" + user.ConnectUserId;
- url += "&key=userpreferences";
-
- var options = new HttpRequestOptions
- {
- Url = url,
- CancellationToken = cancellationToken
- };
-
- var postData = new Dictionary<string, string>();
- postData["data"] = _json.SerializeToString(ConnectUserPreferences.FromUserConfiguration(user.Configuration));
- options.SetPostData(postData);
-
- SetServerAccessToken(options);
- SetApplicationHeader(options);
-
- try
- {
- // No need to examine the response
- using (var stream = (await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)).Content)
- {
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error uploading user preferences", ex);
- }
- }
-
- private async Task DownloadUserPreferences(User user, CancellationToken cancellationToken)
- {
-
- }
-
public async Task<User> GetLocalUser(string connectUserId)
{
var user = _userManager.Users
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index 590c5fd3f..a19a122c3 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -26,6 +26,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using CommonIO;
namespace MediaBrowser.Server.Implementations.Dto
@@ -92,11 +93,17 @@ namespace MediaBrowser.Server.Implementations.Dto
var syncDictionary = GetSyncedItemProgressDictionary(syncJobItems);
var list = new List<BaseItemDto>();
+ var programTuples = new List<Tuple<BaseItem, BaseItemDto>> { };
foreach (var item in items)
{
var dto = GetBaseItemDtoInternal(item, options, syncDictionary, user, owner);
+ if (item is LiveTvProgram)
+ {
+ programTuples.Add(new Tuple<BaseItem, BaseItemDto>(item, dto));
+ }
+
var byName = item as IItemByName;
if (byName != null)
@@ -118,6 +125,12 @@ namespace MediaBrowser.Server.Implementations.Dto
list.Add(dto);
}
+ if (programTuples.Count > 0)
+ {
+ var task = _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user);
+ Task.WaitAll(task);
+ }
+
return list;
}
@@ -139,6 +152,13 @@ namespace MediaBrowser.Server.Implementations.Dto
var dto = GetBaseItemDtoInternal(item, options, GetSyncedItemProgressDictionary(syncProgress), user, owner);
+ if (item is LiveTvProgram)
+ {
+ var list = new List<Tuple<BaseItem, BaseItemDto>> { new Tuple<BaseItem, BaseItemDto>(item, dto) };
+ var task = _livetvManager().AddInfoToProgramDto(list, options.Fields, user);
+ Task.WaitAll(task);
+ }
+
var byName = item as IItemByName;
if (byName != null)
@@ -393,11 +413,6 @@ namespace MediaBrowser.Server.Implementations.Dto
_livetvManager().AddInfoToRecordingDto(item, dto, user);
}
- else if (item is LiveTvProgram)
- {
- _livetvManager().AddInfoToProgramDto(item, dto, fields, user);
- }
-
return dto;
}
@@ -639,6 +654,8 @@ namespace MediaBrowser.Server.Implementations.Dto
private IEnumerable<string> GetCacheTags(BaseItem item, ImageType type, int limit)
{
return item.GetImages(type)
+ // Convert to a list now in case GetImageCacheTag is slow
+ .ToList()
.Select(p => GetImageCacheTag(item, p))
.Where(i => i != null)
.Take(limit)
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
index 51a104241..703096a2b 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
+++ b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
@@ -213,8 +213,18 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
if (userSessions.Count > 0)
{
- var info = GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo,
- foldersRemovedFrom, id);
+ LibraryUpdateInfo info;
+
+ try
+ {
+ info = GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo,
+ foldersRemovedFrom, id);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in GetLibraryUpdateInfo", ex);
+ return;
+ }
foreach (var userSession in userSessions)
{
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs
index be2817fd2..2473f3af6 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs
+++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs
@@ -57,7 +57,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
CancellationToken = cancellationToken,
// Seeing block length errors
- EnableHttpCompression = false
+ EnableHttpCompression = false,
+
+ LogRequest = false
};
options.SetPostData(data);
@@ -99,7 +101,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
CancellationToken = cancellationToken,
// Seeing block length errors
- EnableHttpCompression = false
+ EnableHttpCompression = false,
+
+ LogRequest = false
};
options.SetPostData(data);
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
index 9d43dabcd..f9e167a8f 100644
--- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
+++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
@@ -64,6 +64,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
FileSize = new FileInfo(path).Length
};
+ if (_libraryMonitor.IsPathLocked(path))
+ {
+ result.Status = FileSortingStatus.Failure;
+ result.StatusMessage = "Path is locked by other processes. Please try again later.";
+ return result;
+ }
+
var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
var resolver = new Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger());
@@ -135,7 +142,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
if (previousResult != null)
{
// Don't keep saving the same result over and over if nothing has changed
- if (previousResult.Status == result.Status && result.Status != FileSortingStatus.Success)
+ if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)
{
return previousResult;
}
@@ -150,7 +157,43 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
{
var result = _organizationService.GetResult(request.ResultId);
- var series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId));
+ Series series = null;
+
+ if (request.NewSeriesProviderIds.Count > 0)
+ {
+ // We're having a new series here
+ SeriesInfo seriesRequest = new SeriesInfo();
+ seriesRequest.ProviderIds = request.NewSeriesProviderIds;
+
+ var refreshOptions = new MetadataRefreshOptions(_fileSystem);
+ series = new Series();
+ series.Id = Guid.NewGuid();
+ series.Name = request.NewSeriesName;
+
+ int year;
+ if (int.TryParse(request.NewSeriesYear, out year))
+ {
+ series.ProductionYear = year;
+ }
+
+ var seriesFolderName = series.Name;
+ if (series.ProductionYear.HasValue)
+ {
+ seriesFolderName = string.Format("{0} ({1})", seriesFolderName, series.ProductionYear);
+ }
+
+ series.Path = Path.Combine(request.TargetFolder, seriesFolderName);
+
+ series.ProviderIds = request.NewSeriesProviderIds;
+
+ await series.RefreshMetadata(refreshOptions, cancellationToken);
+ }
+
+ if (series == null)
+ {
+ // Existing Series
+ series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId));
+ }
await OrganizeEpisode(result.OriginalPath,
series,
@@ -243,16 +286,29 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
{
if (options.TvOptions.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
{
- _logger.Info("File {0} already copied to new path {1}, stopping organization", sourcePath, newPath);
+ var msg = string.Format("File '{0}' already copied to new path '{1}', stopping organization", sourcePath, newPath);
+ _logger.Info(msg);
+ result.Status = FileSortingStatus.SkippedExisting;
+ result.StatusMessage = msg;
+ return;
+ }
+
+ if (fileExists)
+ {
+ var msg = string.Format("File '{0}' already exists as '{1}', stopping organization", sourcePath, newPath);
+ _logger.Info(msg);
result.Status = FileSortingStatus.SkippedExisting;
- result.StatusMessage = string.Empty;
+ result.StatusMessage = msg;
+ result.TargetPath = newPath;
return;
}
- if (fileExists || otherDuplicatePaths.Count > 0)
+ if (otherDuplicatePaths.Count > 0)
{
+ var msg = string.Format("File '{0}' already exists as '{1}', stopping organization", sourcePath, otherDuplicatePaths);
+ _logger.Info(msg);
result.Status = FileSortingStatus.SkippedExisting;
- result.StatusMessage = string.Empty;
+ result.StatusMessage = msg;
result.DuplicatePaths = otherDuplicatePaths;
return;
}
@@ -502,7 +558,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
}
}
- return series ?? new Series();
+ return series;
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
index e69ff367a..c284007f7 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -348,6 +348,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer
return Task.FromResult(true);
}
+ if (string.Equals(localPath, "/emby/pin", StringComparison.OrdinalIgnoreCase))
+ {
+ httpRes.RedirectToUrl("web/pin.html");
+ return Task.FromResult(true);
+ }
+
if (!string.IsNullOrWhiteSpace(GlobalResponse))
{
httpRes.StatusCode = 503;
diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs
index f6b14fcab..d8f7d889c 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs
@@ -134,20 +134,17 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues)
{
- if (!_config.Configuration.IsStartupWizardCompleted &&
- authAttribtues.AllowBeforeStartupWizard)
+ if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard)
{
return true;
}
- return _config.Configuration.InsecureApps9.Contains(auth.Client ?? string.Empty,
- StringComparer.OrdinalIgnoreCase);
+ return false;
}
private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, AuthenticationInfo tokenInfo)
{
- if (!_config.Configuration.IsStartupWizardCompleted &&
- authAttribtues.AllowBeforeStartupWizard)
+ if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard)
{
return true;
}
diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
index 75d54a80a..357f5c976 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -45,7 +45,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
{
var auth = GetAuthorizationDictionary(httpReq);
- string userId = null;
string deviceId = null;
string device = null;
string client = null;
@@ -53,9 +52,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
if (auth != null)
{
- // TODO: Remove this
- auth.TryGetValue("UserId", out userId);
-
auth.TryGetValue("DeviceId", out deviceId);
auth.TryGetValue("Device", out device);
auth.TryGetValue("Client", out client);
@@ -78,7 +74,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
Client = client,
Device = device,
DeviceId = deviceId,
- UserId = userId,
Version = version,
Token = token
};
diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
index 764eb7c68..0559e08ea 100644
--- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
+++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
@@ -78,6 +78,12 @@ namespace MediaBrowser.Server.Implementations.IO
TemporarilyIgnore(path);
}
+ public bool IsPathLocked(string path)
+ {
+ var lockedPaths = _tempIgnoredPaths.Keys.ToList();
+ return lockedPaths.Any(i => string.Equals(i, path, StringComparison.OrdinalIgnoreCase) || _fileSystem.ContainsSubPath(i, path));
+ }
+
public async void ReportFileSystemChangeComplete(string path, bool refreshPath)
{
if (string.IsNullOrEmpty(path))
@@ -658,7 +664,7 @@ namespace MediaBrowser.Server.Implementations.IO
while (item == null && !string.IsNullOrEmpty(path))
{
- item = LibraryManager.RootFolder.FindByPath(path);
+ item = LibraryManager.FindByPath(path);
path = Path.GetDirectoryName(path);
}
@@ -690,8 +696,21 @@ namespace MediaBrowser.Server.Implementations.IO
foreach (var watcher in _fileSystemWatchers.Values.ToList())
{
+ watcher.Created -= watcher_Changed;
+ watcher.Deleted -= watcher_Changed;
+ watcher.Renamed -= watcher_Changed;
watcher.Changed -= watcher_Changed;
- watcher.EnableRaisingEvents = false;
+
+ try
+ {
+ watcher.EnableRaisingEvents = false;
+ }
+ catch (InvalidOperationException)
+ {
+ // Seeing this under mono on linux sometimes
+ // Collection was modified; enumeration operation may not execute.
+ }
+
watcher.Dispose();
}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index 333b1fbe9..721603efe 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -788,6 +788,29 @@ namespace MediaBrowser.Server.Implementations.Library
return _userRootFolder;
}
+ public BaseItem FindByPath(string path)
+ {
+ var query = new InternalItemsQuery
+ {
+ Path = path
+ };
+
+ // Only use the database result if there's exactly one item, otherwise we run the risk of returning old data that hasn't been cleaned yet.
+ var items = GetItemIds(query).Select(GetItemById).Where(i => i != null).ToArray();
+
+ if (items.Length == 1)
+ {
+ return items[0];
+ }
+
+ if (items.Length == 0)
+ {
+ return null;
+ }
+
+ return RootFolder.FindByPath(path);
+ }
+
/// <summary>
/// Gets a Person
/// </summary>
diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
index b132eedec..e4a085f42 100644
--- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
@@ -30,8 +30,9 @@ namespace MediaBrowser.Server.Implementations.Library
private IMediaSourceProvider[] _providers;
private readonly ILogger _logger;
+ private readonly IUserDataManager _userDataManager;
- public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, ILogger logger, IJsonSerializer jsonSerializer, IFileSystem fileSystem)
+ public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, ILogger logger, IJsonSerializer jsonSerializer, IFileSystem fileSystem, IUserDataManager userDataManager)
{
_itemRepo = itemRepo;
_userManager = userManager;
@@ -39,6 +40,7 @@ namespace MediaBrowser.Server.Implementations.Library
_logger = logger;
_jsonSerializer = jsonSerializer;
_fileSystem = fileSystem;
+ _userDataManager = userDataManager;
}
public void AddParts(IEnumerable<IMediaSourceProvider> providers)
@@ -140,7 +142,7 @@ namespace MediaBrowser.Server.Implementations.Library
{
if (user != null)
{
- SetUserProperties(source, user);
+ SetUserProperties(hasMediaSources, source, user);
}
if (source.Protocol == MediaProtocol.File)
{
@@ -257,25 +259,38 @@ namespace MediaBrowser.Server.Implementations.Library
{
foreach (var source in sources)
{
- SetUserProperties(source, user);
+ SetUserProperties(item, source, user);
}
}
return sources;
}
- private void SetUserProperties(MediaSourceInfo source, User user)
+ private void SetUserProperties(IHasUserData item, MediaSourceInfo source, User user)
{
- var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference)
- ? new string[] { }
- : new[] { user.Configuration.AudioLanguagePreference };
+ var userData = item == null ? new UserItemData() : _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
+
+ SetDefaultAudioStreamIndex(source, userData, user);
+ SetDefaultSubtitleStreamIndex(source, userData, user);
+ }
+ private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user)
+ {
+ if (userData.SubtitleStreamIndex.HasValue && user.Configuration.RememberSubtitleSelections)
+ {
+ var index = userData.SubtitleStreamIndex.Value;
+ // Make sure the saved index is still valid
+ if (index == -1 || source.MediaStreams.Any(i => i.Type == MediaStreamType.Subtitle && i.Index == index))
+ {
+ source.DefaultSubtitleStreamIndex = index;
+ return;
+ }
+ }
+
var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference)
? new List<string> { }
: new List<string> { user.Configuration.SubtitleLanguagePreference };
- source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack);
-
var defaultAudioIndex = source.DefaultAudioStreamIndex;
var audioLangage = defaultAudioIndex == null
? null
@@ -290,6 +305,26 @@ namespace MediaBrowser.Server.Implementations.Library
user.Configuration.SubtitleMode, audioLangage);
}
+ private void SetDefaultAudioStreamIndex(MediaSourceInfo source, UserItemData userData, User user)
+ {
+ if (userData.AudioStreamIndex.HasValue && user.Configuration.RememberAudioSelections)
+ {
+ var index = userData.AudioStreamIndex.Value;
+ // Make sure the saved index is still valid
+ if (source.MediaStreams.Any(i => i.Type == MediaStreamType.Audio && i.Index == index))
+ {
+ source.DefaultAudioStreamIndex = index;
+ return;
+ }
+ }
+
+ var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference)
+ ? new string[] { }
+ : new[] { user.Configuration.AudioLanguagePreference };
+
+ source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack);
+ }
+
private IEnumerable<MediaSourceInfo> SortMediaSources(IEnumerable<MediaSourceInfo> sources)
{
return sources.OrderBy(i =>
@@ -349,11 +384,14 @@ namespace MediaBrowser.Server.Implementations.Library
var json = _jsonSerializer.SerializeToString(mediaSource);
_logger.Debug("Live stream opened: " + json);
var clone = _jsonSerializer.DeserializeFromString<MediaSourceInfo>(json);
-
+
if (!string.IsNullOrWhiteSpace(request.UserId))
{
var user = _userManager.GetUserById(request.UserId);
- SetUserProperties(clone, user);
+ var item = string.IsNullOrWhiteSpace(request.ItemId)
+ ? null
+ : _libraryManager.GetItemById(request.ItemId);
+ SetUserProperties(item, clone, user);
}
return new LiveStreamResponse
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 23424bf3c..c73470b51 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -78,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
}
if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
+ string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
{
return ResolveVideos<Video>(parent, files, directoryService, false);
}
@@ -137,7 +137,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
var resolverResult = resolver.Resolve(files.Select(i => new FileMetadata
{
Id = i.FullName,
- IsFolder = false
+ IsFolder = i.IsDirectory
}).ToList(), suppportMultiEditions).ToList();
@@ -169,9 +169,28 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
result.Items.Add(videoItem);
}
+ result.ExtraFiles.AddRange(files.Where(i => !ContainsFile(resolverResult, i)));
+
return result;
}
+ private bool ContainsFile(List<VideoInfo> result, FileSystemMetadata file)
+ {
+ return result.Any(i => ContainsFile(i, file));
+ }
+
+ private bool ContainsFile(VideoInfo result, FileSystemMetadata file)
+ {
+ return result.Files.Any(i => ContainsFile(i, file)) ||
+ result.AlternateVersions.Any(i => ContainsFile(i, file)) ||
+ result.Extras.Any(i => ContainsFile(i, file));
+ }
+
+ private bool ContainsFile(VideoFileInfo result, FileSystemMetadata file)
+ {
+ return string.Equals(result.Path, file.FullName, StringComparison.OrdinalIgnoreCase);
+ }
+
/// <summary>
/// Resolves the specified args.
/// </summary>
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
index 2161c1454..884e1e322 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
@@ -125,10 +125,21 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
validIds.Add(item.Id);
+ var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview);
+ var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 30;
+
+ var defaultMetadataRefreshMode = performFullRefresh
+ ? MetadataRefreshMode.FullRefresh
+ : MetadataRefreshMode.Default;
+
+ var imageRefreshMode = performFullRefresh
+ ? ImageRefreshMode.FullRefresh
+ : ImageRefreshMode.Default;
+
var options = new MetadataRefreshOptions(_fileSystem)
{
- MetadataRefreshMode = person.Value ? MetadataRefreshMode.Default : MetadataRefreshMode.ValidationOnly,
- ImageRefreshMode = person.Value ? ImageRefreshMode.Default : ImageRefreshMode.ValidationOnly
+ MetadataRefreshMode = person.Value ? defaultMetadataRefreshMode : MetadataRefreshMode.ValidationOnly,
+ ImageRefreshMode = person.Value ? imageRefreshMode : ImageRefreshMode.ValidationOnly
};
await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
index 9ac96165f..d33b2c51d 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
@@ -23,7 +23,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_fileSystem = fileSystem;
}
- public async Task Record(MediaSourceInfo mediaSource, string targetFile, Action onStarted, CancellationToken cancellationToken)
+ public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
{
var httpRequestOptions = new HttpRequestOptions()
{
@@ -42,7 +42,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_logger.Info("Copying recording stream to file stream");
- await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false);
+ var durationToken = new CancellationTokenSource(duration);
+ var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
+
+ await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, linkedToken).ConfigureAwait(false);
}
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 9e4cb66a8..3ab08274c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -87,7 +87,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_timerProvider.RestartTimers();
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
-
}
void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
@@ -104,8 +103,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged;
- private readonly ConcurrentDictionary<string, CancellationTokenSource> _activeRecordings =
- new ConcurrentDictionary<string, CancellationTokenSource>(StringComparer.OrdinalIgnoreCase);
+ private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings =
+ new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase);
public string Name
{
@@ -210,9 +209,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
- if (list.Count > 0)
+ foreach (var provider in GetListingProviders())
{
- foreach (var provider in GetListingProviders())
+ var enabledChannels = list
+ .Where(i => IsListingProviderEnabledForTuner(provider.Item2, i.TunerHostId))
+ .ToList();
+
+ if (enabledChannels.Count > 0)
{
try
{
@@ -228,6 +231,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
}
+
_channelCache = list;
return list;
}
@@ -264,11 +268,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
_timerProvider.Delete(remove);
}
- CancellationTokenSource cancellationTokenSource;
+ ActiveRecordingInfo activeRecordingInfo;
- if (_activeRecordings.TryGetValue(timerId, out cancellationTokenSource))
+ if (_activeRecordings.TryGetValue(timerId, out activeRecordingInfo))
{
- cancellationTokenSource.Cancel();
+ activeRecordingInfo.CancellationTokenSource.Cancel();
}
}
@@ -296,17 +300,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
- try
- {
- _fileSystem.DeleteFile(remove.Path);
- }
- catch (DirectoryNotFoundException)
+ if (!string.IsNullOrWhiteSpace(remove.Path))
{
+ try
+ {
+ _fileSystem.DeleteFile(remove.Path);
+ }
+ catch (DirectoryNotFoundException)
+ {
- }
- catch (FileNotFoundException)
- {
+ }
+ catch (FileNotFoundException)
+ {
+ }
}
_recordingProvider.Delete(remove);
}
@@ -489,6 +496,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
+ private bool IsListingProviderEnabledForTuner(ListingsProviderInfo info, string tunerHostId)
+ {
+ return info.EnableAllTuners || info.EnabledTuners.Contains(tunerHostId ?? string.Empty, StringComparer.OrdinalIgnoreCase);
+ }
+
private async Task<IEnumerable<ProgramInfo>> GetProgramsAsyncInternal(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
{
var channels = await GetChannelsAsync(true, cancellationToken).ConfigureAwait(false);
@@ -496,6 +508,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
foreach (var provider in GetListingProviders())
{
+ if (!IsListingProviderEnabledForTuner(provider.Item2, channel.TunerHostId))
+ {
+ continue;
+ }
+
var programs = await provider.Item1.GetProgramsAsync(provider.Item2, channel.Number, channel.Name, startDateUtc, endDateUtc, cancellationToken)
.ConfigureAwait(false);
@@ -636,11 +653,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
return;
}
- var cancellationTokenSource = new CancellationTokenSource();
+ var activeRecordingInfo = new ActiveRecordingInfo
+ {
+ CancellationTokenSource = new CancellationTokenSource(),
+ TimerId = timer.Id
+ };
- if (_activeRecordings.TryAdd(timer.Id, cancellationTokenSource))
+ if (_activeRecordings.TryAdd(timer.Id, activeRecordingInfo))
{
- await RecordStream(timer, recordingEndDate, cancellationTokenSource.Token).ConfigureAwait(false);
+ await RecordStream(timer, recordingEndDate, activeRecordingInfo, activeRecordingInfo.CancellationTokenSource.Token).ConfigureAwait(false);
}
else
{
@@ -657,7 +678,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
- private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, CancellationToken cancellationToken)
+ private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, ActiveRecordingInfo activeRecordingInfo, CancellationToken cancellationToken)
{
if (timer == null)
{
@@ -712,7 +733,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)).Trim() + ".ts";
recordPath = Path.Combine(recordPath, recordingFileName);
- _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath));
var recordingId = info.Id.GetMD5().ToString("N");
var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.Id, recordingId, StringComparison.OrdinalIgnoreCase));
@@ -760,7 +780,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
try
{
// HDHR doesn't seem to release the tuner right away after first probing with ffmpeg
- await Task.Delay(3000, cancellationToken).ConfigureAwait(false);
+ //await Task.Delay(3000, cancellationToken).ConfigureAwait(false);
var duration = recordingEndDate - DateTime.UtcNow;
@@ -770,6 +790,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
recordPath = Path.ChangeExtension(recordPath, ".mp4");
}
+ recordPath = EnsureFileUnique(recordPath, timer.Id);
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath));
+ activeRecordingInfo.Path = recordPath;
+
+ _libraryMonitor.ReportFileSystemChangeBeginning(recordPath);
recording.Path = recordPath;
recording.Status = RecordingStatus.InProgress;
@@ -778,9 +803,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_logger.Info("Beginning recording. Will record for {0} minutes.", duration.TotalMinutes.ToString(CultureInfo.InvariantCulture));
- var durationToken = new CancellationTokenSource(duration);
- var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
-
_logger.Info("Writing file to path: " + recordPath);
_logger.Info("Opening recording stream from tuner provider");
@@ -790,10 +812,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
isResourceOpen = false;
};
- await recorder.Record(mediaStreamInfo, recordPath, onStarted, linkedToken).ConfigureAwait(false);
+ await recorder.Record(mediaStreamInfo, recordPath, duration, onStarted, cancellationToken).ConfigureAwait(false);
recording.Status = RecordingStatus.Completed;
- _logger.Info("Recording completed");
+ _logger.Info("Recording completed: {0}", recordPath);
}
finally
{
@@ -801,21 +823,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
result.Item2.Release();
}
+
+ _libraryMonitor.ReportFileSystemChangeComplete(recordPath, false);
}
}
catch (OperationCanceledException)
{
- _logger.Info("Recording stopped");
+ _logger.Info("Recording stopped: {0}", recordPath);
recording.Status = RecordingStatus.Completed;
}
catch (Exception ex)
{
- _logger.ErrorException("Error recording", ex);
+ _logger.ErrorException("Error recording to {0}", ex, recordPath);
recording.Status = RecordingStatus.Error;
}
finally
{
- CancellationTokenSource removed;
+ ActiveRecordingInfo removed;
_activeRecordings.TryRemove(timer.Id, out removed);
}
@@ -841,6 +865,40 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
+ private string EnsureFileUnique(string path, string timerId)
+ {
+ var originalPath = path;
+ var index = 1;
+
+ while (FileExists(path, timerId))
+ {
+ var parent = Path.GetDirectoryName(originalPath);
+ var name = Path.GetFileNameWithoutExtension(originalPath);
+ name += "-" + index.ToString(CultureInfo.InvariantCulture);
+
+ path = Path.ChangeExtension(Path.Combine(parent, name), Path.GetExtension(originalPath));
+ index++;
+ }
+
+ return path;
+ }
+
+ private bool FileExists(string path, string timerId)
+ {
+ if (_fileSystem.FileExists(path))
+ {
+ return true;
+ }
+
+ var hasRecordingAtPath = _activeRecordings.Values.ToList().Any(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) && !string.Equals(i.TimerId, timerId, StringComparison.OrdinalIgnoreCase));
+
+ if (hasRecordingAtPath)
+ {
+ return true;
+ }
+ return false;
+ }
+
private async Task<IRecorder> GetRecorder()
{
if (GetConfiguration().EnableRecordingEncoding)
@@ -1024,7 +1082,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
foreach (var pair in _activeRecordings.ToList())
{
- pair.Value.Cancel();
+ pair.Value.CancellationTokenSource.Cancel();
}
}
@@ -1041,5 +1099,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
IsRegistered = true
});
}
+
+ class ActiveRecordingInfo
+ {
+ public string Path { get; set; }
+ public string TimerId { get; set; }
+ public CancellationTokenSource CancellationTokenSource { get; set; }
+ }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
index 5f4d32732..62c9cd171 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
@@ -38,7 +38,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_json = json;
}
- public async Task Record(MediaSourceInfo mediaSource, string targetFile, Action onStarted, CancellationToken cancellationToken)
+ public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
{
_targetPath = targetFile;
_fileSystem.CreateDirectory(Path.GetDirectoryName(targetFile));
@@ -56,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
RedirectStandardInput = true,
FileName = _mediaEncoder.EncoderPath,
- Arguments = GetCommandLineArgs(mediaSource, targetFile),
+ Arguments = GetCommandLineArgs(mediaSource, targetFile, duration),
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false
@@ -88,11 +88,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
// MUST read both stdout and stderr asynchronously or a deadlock may occurr
process.BeginOutputReadLine();
+ onStarted();
+
// Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
StartStreamingLog(process.StandardError.BaseStream, _logFileStream);
- onStarted();
-
// Wait for the file to exist before proceeeding
while (!_hasExited)
{
@@ -100,7 +100,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
- private string GetCommandLineArgs(MediaSourceInfo mediaSource, string targetFile)
+ private string GetCommandLineArgs(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration)
{
string videoArgs;
if (EncodeVideo(mediaSource))
@@ -116,14 +116,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
videoArgs = "-codec:v:0 copy";
}
- var commandLineArgs = "-fflags +genpts -i \"{0}\" -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\"";
+ var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -i \"{0}\" -t {4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\"";
if (mediaSource.ReadAtNativeFramerate)
{
commandLineArgs = "-re " + commandLineArgs;
}
- commandLineArgs = string.Format(commandLineArgs, mediaSource.Path, targetFile, videoArgs, GetAudioArgs(mediaSource));
+ commandLineArgs = string.Format(commandLineArgs, mediaSource.Path, targetFile, videoArgs, GetAudioArgs(mediaSource), _mediaEncoder.GetTimeParameter(duration.Ticks));
return commandLineArgs;
}
@@ -143,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
audioChannels = audioStream.Channels ?? audioChannels;
}
- return "-codec:a:0 aac -strict experimental -ab 320000 -ac " + audioChannels.ToString(CultureInfo.InvariantCulture);
+ return "-codec:a:0 aac -strict experimental -ab 320000";
}
private bool EncodeVideo(MediaSourceInfo mediaSource)
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs
index 12e73c1f3..268a4f751 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs
@@ -7,6 +7,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
public interface IRecorder
{
- Task Record(MediaSourceInfo mediaSource, string targetFile, Action onStarted, CancellationToken cancellationToken);
+ /// <summary>
+ /// Records the specified media source.
+ /// </summary>
+ /// <param name="mediaSource">The media source.</param>
+ /// <param name="targetFile">The target file.</param>
+ /// <param name="duration">The duration.</param>
+ /// <param name="onStarted">The on started.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task.</returns>
+ Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken);
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs
index b29a7562c..68b3f1f71 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs
@@ -13,7 +13,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
where T : class
{
private readonly object _fileDataLock = new object();
- private volatile List<T> _items;
+ private List<T> _items;
private readonly IJsonSerializer _jsonSerializer;
protected readonly ILogger Logger;
private readonly string _dataPath;
@@ -31,17 +31,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public IReadOnlyList<T> GetAll()
{
- if (_items == null)
+ lock (_fileDataLock)
{
- lock (_fileDataLock)
+ if (_items == null)
{
- if (_items == null)
- {
- _items = GetItemsFromFile(_dataPath);
- }
+ _items = GetItemsFromFile(_dataPath);
}
+ return _items;
}
- return _items;
}
private List<T> GetItemsFromFile(string path)
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs
index a5c869d45..37e10d925 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs
@@ -56,13 +56,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
name += " " + info.OriginalAirDate.Value.ToString("yyyy-MM-dd");
}
- if (addHyphen)
- {
- name += " -";
- }
-
if (!string.IsNullOrWhiteSpace(info.EpisodeTitle))
{
+ if (addHyphen)
+ {
+ name += " -";
+ }
+
name += " " + info.EpisodeTitle;
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
index 87d7ff3eb..449943229 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
@@ -951,6 +951,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
public string stationID { get; set; }
public List<Program> programs { get; set; }
public MetadataSchedule metadata { get; set; }
+
+ public Day()
+ {
+ programs = new List<Program>();
+ }
}
//
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
index 04f99cdce..81ad6a387 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
@@ -178,7 +178,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
SourceType = info.SourceType,
Status = info.Status,
ChannelName = channelName,
- Url = info.Url
+ Url = info.Url,
+ CanReset = info.CanReset
};
if (!string.IsNullOrEmpty(info.ChannelId))
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 14bfcba27..abb2710e7 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -350,7 +350,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
foreach (var source in list)
{
- Normalize(source, item.ChannelType == ChannelType.TV);
+ Normalize(source, service, item.ChannelType == ChannelType.TV);
}
return list;
@@ -379,12 +379,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
MediaSourceInfo info;
bool isVideo;
+ ILiveTvService service;
if (isChannel)
{
var channel = GetInternalChannel(id);
isVideo = channel.ChannelType == ChannelType.TV;
- var service = GetService(channel);
+ service = GetService(channel);
_logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId);
info = await service.GetChannelStream(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false);
info.RequiresClosing = true;
@@ -400,7 +401,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
var recording = await GetInternalRecording(id, cancellationToken).ConfigureAwait(false);
isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase);
- var service = GetService(recording);
+ service = GetService(recording);
_logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.ExternalId);
info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false);
@@ -415,7 +416,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
_logger.Info("Live stream info: {0}", _jsonSerializer.SerializeToString(info));
- Normalize(info, isVideo);
+ Normalize(info, service, isVideo);
var data = new LiveStreamData
{
@@ -440,7 +441,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
}
- private void Normalize(MediaSourceInfo mediaSource, bool isVideo)
+ private void Normalize(MediaSourceInfo mediaSource, ILiveTvService service, bool isVideo)
{
if (mediaSource.MediaStreams.Count == 0)
{
@@ -537,6 +538,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
mediaSource.Bitrate = total;
}
}
+
+ if (!(service is EmbyTV.EmbyTV))
+ {
+ // We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says
+ mediaSource.SupportsDirectStream = true;
+ }
}
private async Task<LiveTvChannel> GetChannel(ChannelInfo channelInfo, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
@@ -801,11 +808,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
if (!string.IsNullOrWhiteSpace(info.ImagePath))
{
- item.SetImagePath(ImageType.Primary, info.ImagePath);
+ item.SetImage(new ItemImageInfo
+ {
+ Path = info.ImagePath,
+ Type = ImageType.Primary,
+ IsPlaceholder = true
+ }, 0);
}
else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
{
- item.SetImagePath(ImageType.Primary, info.ImageUrl);
+ item.SetImage(new ItemImageInfo
+ {
+ Path = info.ImageUrl,
+ Type = ImageType.Primary,
+ IsPlaceholder = true
+ }, 0);
}
}
@@ -1472,70 +1489,79 @@ namespace MediaBrowser.Server.Implementations.LiveTv
};
}
- public void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, List<ItemFields> fields, User user = null)
+ public async Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> tuples, List<ItemFields> fields, User user = null)
{
- var program = (LiveTvProgram)item;
-
- dto.StartDate = program.StartDate;
- dto.EpisodeTitle = program.EpisodeTitle;
+ var recordingTuples = new List<Tuple<BaseItemDto, string, string>>();
- if (program.IsRepeat)
- {
- dto.IsRepeat = program.IsRepeat;
- }
- if (program.IsMovie)
- {
- dto.IsMovie = program.IsMovie;
- }
- if (program.IsSeries)
- {
- dto.IsSeries = program.IsSeries;
- }
- if (program.IsSports)
- {
- dto.IsSports = program.IsSports;
- }
- if (program.IsLive)
- {
- dto.IsLive = program.IsLive;
- }
- if (program.IsNews)
- {
- dto.IsNews = program.IsNews;
- }
- if (program.IsKids)
- {
- dto.IsKids = program.IsKids;
- }
- if (program.IsPremiere)
+ foreach (var tuple in tuples)
{
- dto.IsPremiere = program.IsPremiere;
- }
+ var program = (LiveTvProgram)tuple.Item1;
+ var dto = tuple.Item2;
- if (fields.Contains(ItemFields.ChannelInfo))
- {
- var channel = GetInternalChannel(program.ChannelId);
+ dto.StartDate = program.StartDate;
+ dto.EpisodeTitle = program.EpisodeTitle;
+
+ if (program.IsRepeat)
+ {
+ dto.IsRepeat = program.IsRepeat;
+ }
+ if (program.IsMovie)
+ {
+ dto.IsMovie = program.IsMovie;
+ }
+ if (program.IsSeries)
+ {
+ dto.IsSeries = program.IsSeries;
+ }
+ if (program.IsSports)
+ {
+ dto.IsSports = program.IsSports;
+ }
+ if (program.IsLive)
+ {
+ dto.IsLive = program.IsLive;
+ }
+ if (program.IsNews)
+ {
+ dto.IsNews = program.IsNews;
+ }
+ if (program.IsKids)
+ {
+ dto.IsKids = program.IsKids;
+ }
+ if (program.IsPremiere)
+ {
+ dto.IsPremiere = program.IsPremiere;
+ }
- if (channel != null)
+ if (fields.Contains(ItemFields.ChannelInfo))
{
- dto.ChannelName = channel.Name;
- dto.MediaType = channel.MediaType;
+ var channel = GetInternalChannel(program.ChannelId);
- if (channel.HasImage(ImageType.Primary))
+ if (channel != null)
{
- dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel);
+ dto.ChannelName = channel.Name;
+ dto.MediaType = channel.MediaType;
+
+ if (channel.HasImage(ImageType.Primary))
+ {
+ dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel);
+ }
}
}
- }
- if (fields.Contains(ItemFields.ServiceName))
- {
var service = GetService(program);
- if (service != null)
+ var serviceName = service == null ? null : service.Name;
+
+ if (fields.Contains(ItemFields.ServiceName))
{
- dto.ServiceName = service.Name;
+ dto.ServiceName = serviceName;
}
+
+ recordingTuples.Add(new Tuple<BaseItemDto, string, string>(dto, serviceName, program.ExternalId));
}
+
+ await AddRecordingInfo(recordingTuples, CancellationToken.None).ConfigureAwait(false);
}
public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null)
@@ -2343,7 +2369,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
throw new ResourceNotFoundException();
}
- await provider.Validate(info).ConfigureAwait(false);
+ var configurable = provider as IConfigurableTunerHost;
+ if (configurable != null)
+ {
+ await configurable.Validate(info).ConfigureAwait(false);
+ }
var config = GetConfiguration();
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
index 4ebc173b5..fb27631e5 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
@@ -64,7 +64,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
return list;
}
- private List<TunerHostInfo> GetTunerHosts()
+ protected virtual List<TunerHostInfo> GetTunerHosts()
{
return GetConfiguration().TunerHosts
.Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase))
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs
index 92a33993a..0a03e60fa 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs
@@ -90,7 +90,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
await _liveTvManager.SaveTunerHost(new TunerHostInfo
{
Type = HdHomerunHost.DeviceType,
- Url = url
+ Url = url,
+ DataVersion = 1
}).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index 0671a9b56..bdfbee521 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
@@ -14,13 +14,14 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dlna;
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
- public class HdHomerunHost : BaseTunerHost, ITunerHost
+ public class HdHomerunHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
{
private readonly IHttpClient _httpClient;
@@ -47,6 +48,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private const string ChannelIdPrefix = "hdhr_";
+ private string GetChannelId(TunerHostInfo info, Channels i)
+ {
+ var id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture);
+
+ if (info.DataVersion >= 1)
+ {
+ id += '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N");
+ }
+
+ return id;
+ }
+
protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
{
var options = new HttpRequestOptions
@@ -64,8 +77,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
Name = i.GuideName,
Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture),
- Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture),
- IsFavorite = i.Favorite
+ Id = GetChannelId(info, i),
+ IsFavorite = i.Favorite,
+ TunerHostId = info.Id
});
@@ -82,30 +96,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private async Task<string> GetModelInfo(TunerHostInfo info, CancellationToken cancellationToken)
{
- string model = null;
-
using (var stream = await _httpClient.Get(new HttpRequestOptions()
{
- Url = string.Format("{0}/", GetApiUrl(info, false)),
+ Url = string.Format("{0}/discover.json", GetApiUrl(info, false)),
CancellationToken = cancellationToken,
CacheLength = TimeSpan.FromDays(1),
CacheMode = CacheMode.Unconditional,
TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds)
}))
{
- using (var sr = new StreamReader(stream, System.Text.Encoding.UTF8))
- {
- while (!sr.EndOfStream)
- {
- string line = StripXML(sr.ReadLine());
- if (line.StartsWith("Model:")) { model = line.Replace("Model: ", ""); }
- //if (line.StartsWith("Device ID:")) { deviceID = line.Replace("Device ID: ", ""); }
- //if (line.StartsWith("Firmware:")) { firmware = line.Replace("Firmware: ", ""); }
- }
- }
- }
+ var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);
- return model;
+ return response.ModelNumber;
+ }
}
public async Task<List<LiveTvTunerInfo>> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken)
@@ -347,6 +350,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return Config.GetConfiguration<EncodingOptions>("encoding");
}
+ private string GetHdHrIdFromChannelId(string channelId)
+ {
+ return channelId.Split('_')[1];
+ }
+
protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
{
var list = new List<MediaSourceInfo>();
@@ -355,9 +363,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
return list;
}
- channelId = channelId.Substring(ChannelIdPrefix.Length);
+ var hdhrId = GetHdHrIdFromChannelId(channelId);
- list.Add(GetMediaSource(info, channelId, "native"));
+ list.Add(GetMediaSource(info, hdhrId, "native"));
try
{
@@ -366,12 +374,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
if (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1)
{
- list.Insert(0, GetMediaSource(info, channelId, "heavy"));
+ list.Insert(0, GetMediaSource(info, hdhrId, "heavy"));
- list.Add(GetMediaSource(info, channelId, "internet480"));
- list.Add(GetMediaSource(info, channelId, "internet360"));
- list.Add(GetMediaSource(info, channelId, "internet240"));
- list.Add(GetMediaSource(info, channelId, "mobile"));
+ list.Add(GetMediaSource(info, hdhrId, "internet480"));
+ list.Add(GetMediaSource(info, hdhrId, "internet360"));
+ list.Add(GetMediaSource(info, hdhrId, "internet240"));
+ list.Add(GetMediaSource(info, hdhrId, "mobile"));
}
}
catch (Exception ex)
@@ -400,9 +408,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
throw new ArgumentException("Channel not found");
}
- channelId = channelId.Substring(ChannelIdPrefix.Length);
+ var hdhrId = GetHdHrIdFromChannelId(channelId);
- return GetMediaSource(info, channelId, streamId);
+ return GetMediaSource(info, hdhrId, streamId);
}
public async Task Validate(TunerHostInfo info)
@@ -419,5 +427,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return info.Any(i => i.Status == LiveTvTunerStatus.Available);
}
+
+ public class DiscoverResponse
+ {
+ public string FriendlyName { get; set; }
+ public string ModelNumber { get; set; }
+ public string FirmwareName { get; set; }
+ public string FirmwareVersion { get; set; }
+ public string DeviceID { get; set; }
+ public string DeviceAuth { get; set; }
+ public string BaseURL { get; set; }
+ public string LineupURL { get; set; }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index f87d4f43f..523f14dfc 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -8,19 +8,17 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
-using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
{
- public class M3UTunerHost : BaseTunerHost, ITunerHost
+ public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
{
private readonly IFileSystem _fileSystem;
private readonly IHttpClient _httpClient;
@@ -46,65 +44,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
{
- var urlHash = info.Url.GetMD5().ToString("N");
-
- // Read the file and display it line by line.
- using (var reader = new StreamReader(await GetListingsStream(info, cancellationToken).ConfigureAwait(false)))
- {
- return GetChannels(reader, urlHash);
- }
- }
-
- private List<M3UChannel> GetChannels(StreamReader reader, string urlHash)
- {
- var channels = new List<M3UChannel>();
-
- string channnelName = null;
- string channelNumber = null;
- string line;
-
- while ((line = reader.ReadLine()) != null)
- {
- line = line.Trim();
- if (string.IsNullOrWhiteSpace(line))
- {
- continue;
- }
-
- if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase))
- {
- continue;
- }
-
- if (line.StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase))
- {
- line = line.Substring(8);
- Logger.Info("Found m3u channel: {0}", line);
- var parts = line.Split(new[] { ',' }, 2);
- channelNumber = parts[0];
- channnelName = parts[1];
- }
- else if (!string.IsNullOrWhiteSpace(channelNumber))
- {
- channels.Add(new M3UChannel
- {
- Name = channnelName,
- Number = channelNumber,
- Id = ChannelIdPrefix + urlHash + line.GetMD5().ToString("N"),
- Path = line
- });
-
- channelNumber = null;
- channnelName = null;
- }
- }
- return channels;
+ return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false);
}
public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken)
{
- var list = GetConfiguration().TunerHosts
- .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase))
+ var list = GetTunerHosts()
.Select(i => new LiveTvTunerInfo()
{
Name = Name,
@@ -125,18 +70,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
return sources.First();
}
- class M3UChannel : ChannelInfo
- {
- public string Path { get; set; }
-
- public M3UChannel()
- {
- }
- }
-
public async Task Validate(TunerHostInfo info)
{
- using (var stream = await GetListingsStream(info, CancellationToken.None).ConfigureAwait(false))
+ using (var stream = await new M3uParser(Logger, _fileSystem, _httpClient).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false))
{
}
@@ -147,15 +83,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase);
}
- private Task<Stream> GetListingsStream(TunerHostInfo info, CancellationToken cancellationToken)
- {
- if (info.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
- {
- return _httpClient.Get(info.Url, cancellationToken);
- }
- return Task.FromResult(_fileSystem.OpenRead(info.Url));
- }
-
protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
{
var urlHash = info.Url.GetMD5().ToString("N");
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
new file mode 100644
index 000000000..f8f003fa1
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using CommonIO;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Model.Logging;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
+{
+ public class M3uParser
+ {
+ private readonly ILogger _logger;
+ private readonly IFileSystem _fileSystem;
+ private readonly IHttpClient _httpClient;
+
+ public M3uParser(ILogger logger, IFileSystem fileSystem, IHttpClient httpClient)
+ {
+ _logger = logger;
+ _fileSystem = fileSystem;
+ _httpClient = httpClient;
+ }
+
+ public async Task<List<M3UChannel>> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken)
+ {
+ var urlHash = url.GetMD5().ToString("N");
+
+ // Read the file and display it line by line.
+ using (var reader = new StreamReader(await GetListingsStream(url, cancellationToken).ConfigureAwait(false)))
+ {
+ return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId);
+ }
+ }
+
+ public Task<Stream> GetListingsStream(string url, CancellationToken cancellationToken)
+ {
+ if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
+ {
+ return _httpClient.Get(url, cancellationToken);
+ }
+ return Task.FromResult(_fileSystem.OpenRead(url));
+ }
+
+ private List<M3UChannel> GetChannels(StreamReader reader, string urlHash, string channelIdPrefix, string tunerHostId)
+ {
+ var channels = new List<M3UChannel>();
+ string line;
+ string extInf = "";
+ while ((line = reader.ReadLine()) != null)
+ {
+ line = line.Trim();
+ if (string.IsNullOrWhiteSpace(line))
+ {
+ continue;
+ }
+
+ if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase))
+ {
+ continue;
+ }
+
+ if (line.StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase))
+ {
+ extInf = line.Substring(8).Trim();
+ _logger.Info("Found m3u channel: {0}", extInf);
+ }
+ else if (!string.IsNullOrWhiteSpace(extInf))
+ {
+ var channel = GetChannelnfo(extInf, tunerHostId);
+ channel.Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N");
+ channel.Path = line;
+ channels.Add(channel);
+ extInf = "";
+ }
+ }
+ return channels;
+ }
+ private M3UChannel GetChannelnfo(string extInf, string tunerHostId)
+ {
+ var titleIndex = extInf.LastIndexOf(',');
+ var channel = new M3UChannel();
+ channel.TunerHostId = tunerHostId;
+
+ channel.Number = extInf.Trim().Split(' ')[0] ?? "0";
+ channel.Name = extInf.Substring(titleIndex + 1);
+
+ if(channel.Number == "-1") { channel.Number = "0"; }
+
+ //Check for channel number with the format from SatIp
+ int number;
+ var numberIndex = channel.Name.IndexOf('.');
+ if (numberIndex > 0)
+ {
+ if (int.TryParse(channel.Name.Substring(0, numberIndex), out number))
+ {
+ channel.Number = number.ToString();
+ channel.Name = channel.Name.Substring(numberIndex + 1);
+ }
+ }
+ channel.ImageUrl = FindProperty("tvg-logo", extInf, null);
+ channel.Number = FindProperty("tvg-id", extInf, channel.Number);
+ channel.Number = FindProperty("channel-id", extInf, channel.Number);
+ channel.Name = FindProperty("tvg-name", extInf, channel.Name);
+ channel.Name = FindProperty("tvg-id", extInf, channel.Name);
+ return channel;
+
+ }
+ private string FindProperty(string property, string properties, string defaultResult = "")
+ {
+ var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase);
+ var matches = reg.Matches(properties);
+ foreach (Match match in matches)
+ {
+ if (match.Groups[1].Value == property)
+ {
+ return match.Groups[2].Value;
+ }
+ }
+ return defaultResult;
+ }
+ }
+
+
+ public class M3UChannel : ChannelInfo
+ {
+ public string Path { get; set; }
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
index 08c42bb46..6781e498a 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
@@ -1,10 +1,14 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using System.Xml;
using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dlna;
@@ -13,6 +17,7 @@ using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
{
@@ -24,14 +29,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
private readonly ILiveTvManager _liveTvManager;
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
private readonly IHttpClient _httpClient;
+ private readonly IJsonSerializer _json;
- public SatIpDiscovery(IDeviceDiscovery deviceDiscovery, IServerConfigurationManager config, ILogger logger, ILiveTvManager liveTvManager, IHttpClient httpClient)
+ public static SatIpDiscovery Current;
+
+ private readonly List<TunerHostInfo> _discoveredHosts = new List<TunerHostInfo>();
+
+ public List<TunerHostInfo> DiscoveredHosts
+ {
+ get { return _discoveredHosts.ToList(); }
+ }
+
+ public SatIpDiscovery(IDeviceDiscovery deviceDiscovery, IServerConfigurationManager config, ILogger logger, ILiveTvManager liveTvManager, IHttpClient httpClient, IJsonSerializer json)
{
_deviceDiscovery = deviceDiscovery;
_config = config;
_logger = logger;
_liveTvManager = liveTvManager;
_httpClient = httpClient;
+ _json = json;
+ Current = this;
}
public void Run()
@@ -42,7 +59,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
void _deviceDiscovery_DeviceDiscovered(object sender, SsdpMessageEventArgs e)
{
string st = null;
- if (e.Headers.TryGetValue("ST", out st) && string.Equals(st, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase))
+ string nt = null;
+ e.Headers.TryGetValue("ST", out st);
+ e.Headers.TryGetValue("NT", out nt);
+
+ if (string.Equals(st, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(nt, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase))
{
string location;
if (e.Headers.TryGetValue("Location", out location) && !string.IsNullOrWhiteSpace(location))
@@ -61,26 +83,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
try
{
- var options = GetConfiguration();
-
- //if (options.TunerHosts.Any(i =>
- // string.Equals(i.Type, SatIpHost.DeviceType, StringComparison.OrdinalIgnoreCase) &&
- // UriEquals(i.Url, url)))
- //{
- // return;
- //}
+ if (_discoveredHosts.Any(i => string.Equals(i.Type, SatIpHost.DeviceType, StringComparison.OrdinalIgnoreCase) && string.Equals(location, i.Url, StringComparison.OrdinalIgnoreCase)))
+ {
+ return;
+ }
- //// Strip off the port
- //url = new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped).TrimEnd('/');
+ _logger.Debug("Will attempt to add SAT device {0}", location);
+ var info = await GetInfo(location, CancellationToken.None).ConfigureAwait(false);
- //await TestUrl(url).ConfigureAwait(false);
+ _discoveredHosts.Add(info);
+ }
+ catch (OperationCanceledException)
+ {
- //await _liveTvManager.SaveTunerHost(new TunerHostInfo
- //{
- // Type = SatIpHost.DeviceType,
- // Url = url
+ }
+ catch (NotImplementedException)
+ {
- //}).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -92,43 +111,141 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
}
}
- private async Task TestUrl(string url)
+ public void Dispose()
{
- // Test it by pulling down the lineup
- using (await _httpClient.Get(new HttpRequestOptions
+ }
+
+ public async Task<SatIpTunerHostInfo> GetInfo(string url, CancellationToken cancellationToken)
+ {
+ var result = new SatIpTunerHostInfo
{
- Url = string.Format("{0}/lineup.json", url),
- CancellationToken = CancellationToken.None
- }))
+ Url = url,
+ IsEnabled = true,
+ Type = SatIpHost.DeviceType,
+ Tuners = 1,
+ TunersAvailable = 1
+ };
+
+ using (var stream = await _httpClient.Get(url, cancellationToken).ConfigureAwait(false))
+ {
+ using (var streamReader = new StreamReader(stream))
+ {
+ // Use XmlReader for best performance
+ using (var reader = XmlReader.Create(streamReader))
+ {
+ reader.MoveToContent();
+
+ // Loop through each element
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "device":
+ using (var subtree = reader.ReadSubtree())
+ {
+ FillFromDeviceNode(result, subtree);
+ }
+ break;
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (string.IsNullOrWhiteSpace(result.Id))
{
+ throw new NotImplementedException();
}
- }
- private bool UriEquals(string savedUri, string location)
- {
- return string.Equals(NormalizeUrl(location), NormalizeUrl(savedUri), StringComparison.OrdinalIgnoreCase);
- }
+ // Device hasn't implemented an m3u list
+ if (string.IsNullOrWhiteSpace(result.M3UUrl))
+ {
+ result.IsEnabled = false;
+ }
- private string NormalizeUrl(string url)
- {
- if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
+ else if (!result.M3UUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
- url = "http://" + url;
+ var fullM3uUrl = url.Substring(0, url.LastIndexOf('/'));
+ result.M3UUrl = fullM3uUrl + "/" + result.M3UUrl.TrimStart('/');
}
- url = url.TrimEnd('/');
+ _logger.Debug("SAT device result: {0}", _json.SerializeToString(result));
- // Strip off the port
- return new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped);
+ return result;
}
- private LiveTvOptions GetConfiguration()
+ private void FillFromDeviceNode(SatIpTunerHostInfo info, XmlReader reader)
{
- return _config.GetConfiguration<LiveTvOptions>("livetv");
- }
+ reader.MoveToContent();
- public void Dispose()
- {
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.LocalName)
+ {
+ case "UDN":
+ {
+ info.Id = reader.ReadElementContentAsString();
+ break;
+ }
+
+ case "friendlyName":
+ {
+ info.FriendlyName = reader.ReadElementContentAsString();
+ break;
+ }
+
+ case "satip:X_SATIPCAP":
+ case "X_SATIPCAP":
+ {
+ // <satip:X_SATIPCAP xmlns:satip="urn:ses-com:satip">DVBS2-2</satip:X_SATIPCAP>
+ var value = reader.ReadElementContentAsString() ?? string.Empty;
+ var parts = value.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
+ if (parts.Length == 2)
+ {
+ int intValue;
+ if (int.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out intValue))
+ {
+ info.TunersAvailable = intValue;
+ }
+
+ if (int.TryParse(parts[0].Substring(parts[0].Length - 1), NumberStyles.Any, CultureInfo.InvariantCulture, out intValue))
+ {
+ info.Tuners = intValue;
+ }
+ }
+ break;
+ }
+
+ case "satip:X_SATIPM3U":
+ case "X_SATIPM3U":
+ {
+ // <satip:X_SATIPM3U xmlns:satip="urn:ses-com:satip">/channellist.lua?select=m3u</satip:X_SATIPM3U>
+ info.M3UUrl = reader.ReadElementContentAsString();
+ break;
+ }
+
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
}
}
+
+ public class SatIpTunerHostInfo : TunerHostInfo
+ {
+ public int Tuners { get; set; }
+ public int TunersAvailable { get; set; }
+ public string M3UUrl { get; set; }
+ public string FriendlyName { get; set; }
+ }
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs
index 205cdf74e..181169e9a 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs
@@ -1,45 +1,171 @@
-namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using CommonIO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.LiveTv;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Serialization;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
{
- public class SatIpHost /*: BaseTunerHost*/
+ public class SatIpHost : BaseTunerHost, ITunerHost
{
- //public SatIpHost(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder)
- // : base(config, logger, jsonSerializer, mediaEncoder)
- //{
- //}
+ private readonly IFileSystem _fileSystem;
+ private readonly IHttpClient _httpClient;
+
+ public SatIpHost(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient)
+ : base(config, logger, jsonSerializer, mediaEncoder)
+ {
+ _fileSystem = fileSystem;
+ _httpClient = httpClient;
+ }
+
+ private const string ChannelIdPrefix = "sat_";
+
+ protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken)
+ {
+ var satInfo = (SatIpTunerHostInfo) tuner;
- //protected override Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken)
- //{
- // throw new NotImplementedException();
- //}
+ return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(satInfo.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false);
+ }
public static string DeviceType
{
get { return "satip"; }
}
- //public override string Type
- //{
- // get { return DeviceType; }
- //}
+ public override string Type
+ {
+ get { return DeviceType; }
+ }
+
+ protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
+ {
+ var urlHash = tuner.Url.GetMD5().ToString("N");
+ var prefix = ChannelIdPrefix + urlHash;
+ if (!channelId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
+ {
+ return null;
+ }
+
+ var channels = await GetChannels(tuner, true, cancellationToken).ConfigureAwait(false);
+ var m3uchannels = channels.Cast<M3UChannel>();
+ var channel = m3uchannels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase));
+ if (channel != null)
+ {
+ var path = channel.Path;
+ MediaProtocol protocol = MediaProtocol.File;
+ if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Http;
+ }
+ else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Rtmp;
+ }
+ else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Rtsp;
+ }
+
+ var mediaSource = new MediaSourceInfo
+ {
+ Path = channel.Path,
+ Protocol = protocol,
+ MediaStreams = new List<MediaStream>
+ {
+ new MediaStream
+ {
+ Type = MediaStreamType.Video,
+ // Set the index to -1 because we don't know the exact index of the video stream within the container
+ Index = -1,
+ IsInterlaced = true
+ },
+ new MediaStream
+ {
+ Type = MediaStreamType.Audio,
+ // Set the index to -1 because we don't know the exact index of the audio stream within the container
+ Index = -1
+
+ }
+ },
+ RequiresOpening = false,
+ RequiresClosing = false
+ };
+
+ return new List<MediaSourceInfo> { mediaSource };
+ }
+ return new List<MediaSourceInfo> { };
+ }
+
+ protected override async Task<MediaSourceInfo> GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken)
+ {
+ var sources = await GetChannelStreamMediaSources(tuner, channelId, cancellationToken).ConfigureAwait(false);
+
+ return sources.First();
+ }
+
+ protected override async Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
+ {
+ var updatedInfo = await SatIpDiscovery.Current.GetInfo(tuner.Url, cancellationToken).ConfigureAwait(false);
- //protected override Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
- //{
- // throw new NotImplementedException();
- //}
+ return updatedInfo.TunersAvailable > 0;
+ }
+
+ protected override bool IsValidChannelId(string channelId)
+ {
+ return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase);
+ }
- //protected override Task<MediaSourceInfo> GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken)
- //{
- // throw new NotImplementedException();
- //}
+ protected override List<TunerHostInfo> GetTunerHosts()
+ {
+ return SatIpDiscovery.Current.DiscoveredHosts;
+ }
- //protected override Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
- //{
- // throw new NotImplementedException();
- //}
+ public string Name
+ {
+ get { return "Sat IP"; }
+ }
- //protected override bool IsValidChannelId(string channelId)
- //{
- // throw new NotImplementedException();
- //}
+ public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken)
+ {
+ var list = GetTunerHosts()
+ .SelectMany(i => GetTunerInfos(i, cancellationToken))
+ .ToList();
+
+ return Task.FromResult(list);
+ }
+
+ public List<LiveTvTunerInfo> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken)
+ {
+ var satInfo = (SatIpTunerHostInfo) info;
+
+ var list = new List<LiveTvTunerInfo>();
+
+ for (var i = 0; i < satInfo.Tuners; i++)
+ {
+ list.Add(new LiveTvTunerInfo
+ {
+ Name = satInfo.FriendlyName ?? Name,
+ SourceType = Type,
+ Status = LiveTvTunerStatus.Available,
+ Id = info.Url.GetMD5().ToString("N") + i.ToString(CultureInfo.InvariantCulture),
+ Url = info.Url
+ });
+ }
+
+ return list;
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 5f2fab457..a511d31b5 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -43,7 +43,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="Emby.XmlTv, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -52,9 +52,9 @@
<Reference Include="Interfaces.IO">
<HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath>
</Reference>
- <Reference Include="MediaBrowser.Naming, Version=1.0.5884.23751, Culture=neutral, processorArchitecture=MSIL">
+ <Reference Include="MediaBrowser.Naming, Version=1.0.5891.29179, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\MediaBrowser.Naming.1.0.0.47\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
+ <HintPath>..\packages\MediaBrowser.Naming.1.0.0.48\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
</Reference>
<Reference Include="MoreLinq">
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
@@ -65,9 +65,9 @@
<Reference Include="ServiceStack.Api.Swagger">
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath>
</Reference>
- <Reference Include="SocketHttpListener, Version=1.0.5840.28948, Culture=neutral, processorArchitecture=MSIL">
+ <Reference Include="SocketHttpListener, Version=1.0.5900.37035, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\SocketHttpListener.1.0.0.25\lib\net45\SocketHttpListener.dll</HintPath>
+ <HintPath>..\packages\SocketHttpListener.1.0.0.27\lib\net45\SocketHttpListener.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -234,6 +234,7 @@
<Compile Include="LiveTv\TunerHosts\BaseTunerHost.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunHost.cs" />
<Compile Include="LiveTv\TunerHosts\HdHomerun\HdHomerunDiscovery.cs" />
+ <Compile Include="LiveTv\TunerHosts\M3uParser.cs" />
<Compile Include="LiveTv\TunerHosts\M3UTunerHost.cs" />
<Compile Include="LiveTv\ProgramImageProvider.cs" />
<Compile Include="LiveTv\RecordingImageProvider.cs" />
diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
index 6ca1bae6d..5f1bf0216 100644
--- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
@@ -239,7 +239,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
typeof(Year).Name,
typeof(Channel).Name,
typeof(AggregateFolder).Name,
- typeof(CollectionFolder).Name
+ typeof(CollectionFolder).Name,
+
+ // LiveTVManager handles recordings
+ typeof(LiveTvAudioRecording).Name,
+ typeof(LiveTvVideoRecording).Name
}
});
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index a85872951..cd439d1f2 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -130,6 +130,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
"create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID)",
"create index if not exists idx_TypedBaseItems on TypedBaseItems(guid)",
+ "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)",
"create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)",
"create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
@@ -1014,7 +1015,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
if (!reader.IsDBNull(31))
{
- item.OfficialRating = reader.GetString(31);
+ item.OfficialRatingDescription = reader.GetString(31);
}
if (!reader.IsDBNull(32))
@@ -1804,6 +1805,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.Parameters.Add(cmd, "@ParentId", DbType.Guid).Value = query.ParentId.Value;
}
+ if (!string.IsNullOrWhiteSpace(query.Path))
+ {
+ whereClauses.Add("Path=@Path");
+ cmd.Parameters.Add(cmd, "@Path", DbType.String).Value = query.Path;
+ }
+
if (query.MinEndDate.HasValue)
{
whereClauses.Add("EndDate>=@MinEndDate");
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
index 8b86d19a2..63c41c71f 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
@@ -56,6 +56,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
};
_connection.RunQueries(queries, Logger);
+
+ _connection.AddColumn(Logger, "userdata", "AudioStreamIndex", "int");
+ _connection.AddColumn(Logger, "userdata", "SubtitleStreamIndex", "int");
}
/// <summary>
@@ -127,7 +130,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
using (var cmd = _connection.CreateCommand())
{
- cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate)";
+ cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate,@AudioStreamIndex,@SubtitleStreamIndex)";
cmd.Parameters.Add(cmd, "@key", DbType.String).Value = key;
cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
@@ -137,6 +140,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.Parameters.Add(cmd, "@isFavorite", DbType.Boolean).Value = userData.IsFavorite;
cmd.Parameters.Add(cmd, "@playbackPositionTicks", DbType.Int64).Value = userData.PlaybackPositionTicks;
cmd.Parameters.Add(cmd, "@lastPlayedDate", DbType.DateTime).Value = userData.LastPlayedDate;
+ cmd.Parameters.Add(cmd, "@AudioStreamIndex", DbType.Int32).Value = userData.AudioStreamIndex;
+ cmd.Parameters.Add(cmd, "@SubtitleStreamIndex", DbType.Int32).Value = userData.SubtitleStreamIndex;
cmd.Transaction = transaction;
@@ -199,7 +204,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
using (var cmd = _connection.CreateCommand())
{
- cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate)";
+ cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate,@AudioStreamIndex,@SubtitleStreamIndex)";
cmd.Parameters.Add(cmd, "@key", DbType.String).Value = userItemData.Key;
cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
@@ -209,6 +214,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.Parameters.Add(cmd, "@isFavorite", DbType.Boolean).Value = userItemData.IsFavorite;
cmd.Parameters.Add(cmd, "@playbackPositionTicks", DbType.Int64).Value = userItemData.PlaybackPositionTicks;
cmd.Parameters.Add(cmd, "@lastPlayedDate", DbType.DateTime).Value = userItemData.LastPlayedDate;
+ cmd.Parameters.Add(cmd, "@AudioStreamIndex", DbType.Int32).Value = userItemData.AudioStreamIndex;
+ cmd.Parameters.Add(cmd, "@SubtitleStreamIndex", DbType.Int32).Value = userItemData.SubtitleStreamIndex;
cmd.Transaction = transaction;
@@ -275,7 +282,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
using (var cmd = _connection.CreateCommand())
{
- cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where key = @key and userId=@userId";
+ cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from userdata where key = @key and userId=@userId";
cmd.Parameters.Add(cmd, "@key", DbType.String).Value = key;
cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
@@ -310,7 +317,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
using (var cmd = _connection.CreateCommand())
{
- cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where userId=@userId";
+ cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from userdata where userId=@userId";
cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
@@ -350,6 +357,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
userData.LastPlayedDate = reader.GetDateTime(7).ToUniversalTime();
}
+ if (!reader.IsDBNull(8))
+ {
+ userData.AudioStreamIndex = reader.GetInt32(8);
+ }
+
+ if (!reader.IsDBNull(9))
+ {
+ userData.SubtitleStreamIndex = reader.GetInt32(9);
+ }
+
return userData;
}
diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
index c30d35ed2..4a69646f8 100644
--- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
@@ -1,6 +1,5 @@
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
@@ -14,6 +13,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Server.Implementations.Photos
{
@@ -47,6 +47,41 @@ namespace MediaBrowser.Server.Implementations.Photos
};
}
+ private IEnumerable<ImageType> GetEnabledImages(IHasImages item)
+ {
+ //var options = ProviderManager.GetMetadataOptions(item);
+
+ return GetSupportedImages(item);
+ //return GetSupportedImages(item).Where(i => IsEnabled(options, i, item)).ToList();
+ }
+
+ private bool IsEnabled(MetadataOptions options, ImageType type, IHasImages item)
+ {
+ if (type == ImageType.Backdrop)
+ {
+ if (item.LockedFields.Contains(MetadataFields.Backdrops))
+ {
+ return false;
+ }
+ }
+ else if (type == ImageType.Screenshot)
+ {
+ if (item.LockedFields.Contains(MetadataFields.Screenshots))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (item.LockedFields.Contains(MetadataFields.Images))
+ {
+ return false;
+ }
+ }
+
+ return options.IsEnabled(type);
+ }
+
public async Task<ItemUpdateType> FetchAsync(T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
if (!Supports(item))
@@ -55,7 +90,7 @@ namespace MediaBrowser.Server.Implementations.Photos
}
var updateType = ItemUpdateType.None;
- var supportedImages = GetSupportedImages(item).ToList();
+ var supportedImages = GetEnabledImages(item).ToList();
if (supportedImages.Contains(ImageType.Primary))
{
@@ -69,7 +104,6 @@ namespace MediaBrowser.Server.Implementations.Photos
updateType = updateType | thumbResult;
}
-
return updateType;
}
@@ -220,7 +254,7 @@ namespace MediaBrowser.Server.Implementations.Photos
return false;
}
- var supportedImages = GetSupportedImages(item).ToList();
+ var supportedImages = GetEnabledImages(item).ToList();
if (supportedImages.Contains(ImageType.Primary) && HasChanged(item, ImageType.Primary))
{
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index a9ce5ba54..08953b0be 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -680,7 +680,7 @@ namespace MediaBrowser.Server.Implementations.Session
foreach (var user in users)
{
- await OnPlaybackProgress(user.Id, key, libraryItem, info.PositionTicks).ConfigureAwait(false);
+ await OnPlaybackProgress(user, key, libraryItem, info).ConfigureAwait(false);
}
}
@@ -712,15 +712,40 @@ namespace MediaBrowser.Server.Implementations.Session
StartIdleCheckTimer();
}
- private async Task OnPlaybackProgress(Guid userId, string userDataKey, BaseItem item, long? positionTicks)
+ private async Task OnPlaybackProgress(User user, string userDataKey, BaseItem item, PlaybackProgressInfo info)
{
- var data = _userDataRepository.GetUserData(userId, userDataKey);
+ var data = _userDataRepository.GetUserData(user.Id, userDataKey);
+
+ var positionTicks = info.PositionTicks;
if (positionTicks.HasValue)
{
_userDataRepository.UpdatePlayState(item, data, positionTicks.Value);
- await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false);
+ UpdatePlaybackSettings(user, info, data);
+
+ await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false);
+ }
+ }
+
+ private void UpdatePlaybackSettings(User user, PlaybackProgressInfo info, UserItemData data)
+ {
+ if (user.Configuration.RememberAudioSelections)
+ {
+ data.AudioStreamIndex = info.AudioStreamIndex;
+ }
+ else
+ {
+ data.AudioStreamIndex = null;
+ }
+
+ if (user.Configuration.RememberSubtitleSelections)
+ {
+ data.SubtitleStreamIndex = info.SubtitleStreamIndex;
+ }
+ else
+ {
+ data.SubtitleStreamIndex = null;
}
}
@@ -958,6 +983,26 @@ namespace MediaBrowser.Server.Implementations.Session
}
}
+ if (user != null && command.ItemIds.Length == 1 && user.Configuration.EnableNextEpisodeAutoPlay)
+ {
+ var episode = _libraryManager.GetItemById(command.ItemIds[0]) as Episode;
+ if (episode != null)
+ {
+ var series = episode.Series;
+ if (series != null)
+ {
+ var episodes = series.GetEpisodes(user, false, false)
+ .SkipWhile(i => i.Id != episode.Id)
+ .ToList();
+
+ if (episodes.Count > 0)
+ {
+ command.ItemIds = episodes.Select(i => i.Id.ToString("N")).ToArray();
+ }
+ }
+ }
+ }
+
var controllingSession = GetSession(controllingSessionId);
AssertCanControl(session, controllingSession);
if (controllingSession.UserId.HasValue)
@@ -1268,7 +1313,17 @@ namespace MediaBrowser.Server.Implementations.Session
/// </summary>
/// <param name="request">The request.</param>
/// <returns>Task{SessionInfo}.</returns>
- public async Task<AuthenticationResult> AuthenticateNewSession(AuthenticationRequest request)
+ public Task<AuthenticationResult> AuthenticateNewSession(AuthenticationRequest request)
+ {
+ return AuthenticateNewSessionInternal(request, true);
+ }
+
+ public Task<AuthenticationResult> CreateNewSession(AuthenticationRequest request)
+ {
+ return AuthenticateNewSessionInternal(request, false);
+ }
+
+ private async Task<AuthenticationResult> AuthenticateNewSessionInternal(AuthenticationRequest request, bool enforcePassword)
{
var user = _userManager.Users
.FirstOrDefault(i => string.Equals(request.Username, i.Name, StringComparison.OrdinalIgnoreCase));
@@ -1281,13 +1336,16 @@ namespace MediaBrowser.Server.Implementations.Session
}
}
- var result = await _userManager.AuthenticateUser(request.Username, request.PasswordSha1, request.PasswordMd5, request.RemoteEndPoint).ConfigureAwait(false);
-
- if (!result)
+ if (enforcePassword)
{
- EventHelper.FireEventIfNotNull(AuthenticationFailed, this, new GenericEventArgs<AuthenticationRequest>(request), _logger);
+ var result = await _userManager.AuthenticateUser(request.Username, request.PasswordSha1, request.PasswordMd5, request.RemoteEndPoint).ConfigureAwait(false);
+
+ if (!result)
+ {
+ EventHelper.FireEventIfNotNull(AuthenticationFailed, this, new GenericEventArgs<AuthenticationRequest>(request), _logger);
- throw new SecurityException("Invalid user or password entered.");
+ throw new SecurityException("Invalid user or password entered.");
+ }
}
var token = await GetAuthorizationToken(user.Id.ToString("N"), request.DeviceId, request.App, request.AppVersion, request.DeviceName).ConfigureAwait(false);
@@ -1310,7 +1368,8 @@ namespace MediaBrowser.Server.Implementations.Session
ServerId = _appHost.SystemId
};
}
-
+
+
private async Task<string> GetAuthorizationToken(string userId, string deviceId, string app, string appVersion, string deviceName)
{
var existing = _authRepo.Get(new AuthenticationInfoQuery
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs
index b6242950f..fb4e0c6be 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs
@@ -10,11 +10,11 @@ namespace MediaBrowser.Server.Implementations.Sync
{
if (string.Equals(quality, "medium", StringComparison.OrdinalIgnoreCase))
{
- profileBitrate = Math.Min(Convert.ToInt32(profileBitrate.Value * .7), 4000000);
+ profileBitrate = Math.Min(profileBitrate.Value, 4000000);
}
else if (string.Equals(quality, "low", StringComparison.OrdinalIgnoreCase))
{
- profileBitrate = Math.Min(Convert.ToInt32(profileBitrate.Value * .5), 1500000);
+ profileBitrate = Math.Min(profileBitrate.Value, 1500000);
}
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
index 95934908d..7086735c0 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
@@ -19,6 +19,7 @@ using MediaBrowser.Model.Sync;
using MoreLinq;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
@@ -125,7 +126,23 @@ namespace MediaBrowser.Server.Implementations.Sync
private string GetSyncJobItemName(BaseItem item)
{
- return item.Name;
+ var name = item.Name;
+ var episode = item as Episode;
+
+ if (episode != null)
+ {
+ if (episode.IndexNumber.HasValue)
+ {
+ name = "E" + episode.IndexNumber.Value.ToString(CultureInfo.InvariantCulture) + " - " + name;
+ }
+
+ if (episode.ParentIndexNumber.HasValue)
+ {
+ name = "S" + episode.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture) + ", " + name;
+ }
+ }
+
+ return name;
}
public Task UpdateJobStatus(string id)
@@ -291,6 +308,11 @@ namespace MediaBrowser.Server.Implementations.Sync
throw new ArgumentException("Unrecognized category: " + category);
}
+ if (parent == null)
+ {
+ return new List<BaseItem>();
+ }
+
query.User = user;
var result = await parent.GetItems(query).ConfigureAwait(false);
@@ -321,6 +343,12 @@ namespace MediaBrowser.Server.Implementations.Sync
return series.GetEpisodes(user, false, false);
}
+ var season = item as Season;
+ if (season != null)
+ {
+ return season.GetEpisodes(user, false, false);
+ }
+
if (item.IsFolder)
{
var folder = (Folder)item;
@@ -360,6 +388,9 @@ namespace MediaBrowser.Server.Implementations.Sync
{
await EnsureSyncJobItems(null, cancellationToken).ConfigureAwait(false);
+ // Look job items that are supposedly transfering, but need to be requeued because the synced files have been deleted somehow
+ await HandleDeletedSyncFiles(cancellationToken).ConfigureAwait(false);
+
// If it already has a converting status then is must have been aborted during conversion
var result = _syncManager.GetJobItems(new SyncJobItemQuery
{
@@ -372,6 +403,28 @@ namespace MediaBrowser.Server.Implementations.Sync
CleanDeadSyncFiles();
}
+ private async Task HandleDeletedSyncFiles(CancellationToken cancellationToken)
+ {
+ // Look job items that are supposedly transfering, but need to be requeued because the synced files have been deleted somehow
+ var result = _syncManager.GetJobItems(new SyncJobItemQuery
+ {
+ Statuses = new[] { SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Transferring },
+ AddMetadata = false
+ });
+
+ foreach (var item in result.Items)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (string.IsNullOrWhiteSpace(item.OutputPath) || !_fileSystem.FileExists(item.OutputPath))
+ {
+ item.Status = SyncJobItemStatus.Queued;
+ await _syncManager.UpdateSyncJobItemInternal(item).ConfigureAwait(false);
+ await UpdateJobStatus(item.JobId).ConfigureAwait(false);
+ }
+ }
+ }
+
private void CleanDeadSyncFiles()
{
// TODO
@@ -699,7 +752,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var path = Path.Combine(temporaryPath, filename);
- _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(path));
using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, cancellationToken).ConfigureAwait(false))
{
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
index 50a960956..8ebc8d91e 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
@@ -559,6 +559,12 @@ namespace MediaBrowser.Server.Implementations.Sync
jobItem.Status = SyncJobItemStatus.Synced;
jobItem.Progress = 100;
+ await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false);
+
+ var processor = GetSyncJobProcessor();
+
+ await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
+
if (!string.IsNullOrWhiteSpace(jobItem.TemporaryPath))
{
try
@@ -573,12 +579,6 @@ namespace MediaBrowser.Server.Implementations.Sync
_logger.ErrorException("Error deleting temporary job file: {0}", ex, jobItem.OutputPath);
}
}
-
- await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false);
-
- var processor = GetSyncJobProcessor();
-
- await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false);
}
private SyncJobProcessor GetSyncJobProcessor()
@@ -1015,7 +1015,7 @@ namespace MediaBrowser.Server.Implementations.Sync
{
var jobItem = _repo.GetJobItem(id);
- if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.ReadyToTransfer && jobItem.Status != SyncJobItemStatus.Converting && jobItem.Status != SyncJobItemStatus.Failed && jobItem.Status != SyncJobItemStatus.Synced)
+ if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.ReadyToTransfer && jobItem.Status != SyncJobItemStatus.Converting && jobItem.Status != SyncJobItemStatus.Failed && jobItem.Status != SyncJobItemStatus.Synced && jobItem.Status != SyncJobItemStatus.Transferring)
{
throw new ArgumentException("Operation is not valid for this job item");
}
diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config
index 816f85b42..772790f37 100644
--- a/MediaBrowser.Server.Implementations/packages.config
+++ b/MediaBrowser.Server.Implementations/packages.config
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="Emby.XmlTv" version="1.0.0.48" targetFramework="net45" />
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
- <package id="MediaBrowser.Naming" version="1.0.0.47" targetFramework="net45" />
+ <package id="MediaBrowser.Naming" version="1.0.0.48" targetFramework="net45" />
<package id="Mono.Nat" version="1.2.24.0" targetFramework="net45" />
<package id="morelinq" version="1.4.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
- <package id="SocketHttpListener" version="1.0.0.25" targetFramework="net45" />
+ <package id="SocketHttpListener" version="1.0.0.27" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj
index 7ad1c55f1..dde4c544e 100644
--- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj
+++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj
@@ -476,6 +476,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\photos.html">
<Link>Resources\dashboard-ui\photos.html</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\pin.html">
+ <Link>Resources\dashboard-ui\pin.html</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\playbackconfiguration.html">
<Link>Resources\dashboard-ui\playbackconfiguration.html</Link>
</BundleResource>
@@ -1316,6 +1319,18 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.css">
+ <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.css</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.js">
+ <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\confirm\confirm.js">
+ <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\confirm\confirm.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\confirm\nativeconfirm.js">
+ <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\confirm\nativeconfirm.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\images\basicimagefetcher.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\images\basicimagefetcher.js</Link>
</BundleResource>
@@ -1877,6 +1892,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-demo-helpers\.gitignore">
<Link>Resources\dashboard-ui\bower_components\iron-demo-helpers\.gitignore</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-demo-helpers\.travis.yml">
+ <Link>Resources\dashboard-ui\bower_components\iron-demo-helpers\.travis.yml</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-demo-helpers\CONTRIBUTING.md">
<Link>Resources\dashboard-ui\bower_components\iron-demo-helpers\CONTRIBUTING.md</Link>
</BundleResource>
@@ -2012,6 +2030,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\index.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\index.html</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout-classes.html">
+ <Link>Resources\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout-classes.html</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout.html</Link>
</BundleResource>
@@ -2021,12 +2042,18 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\classes\iron-shadow-flex-layout.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\classes\iron-shadow-flex-layout.html</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\demo\demo-snippet.html">
- <Link>Resources\dashboard-ui\bower_components\iron-flex-layout\demo\demo-snippet.html</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\demo\index.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\demo\index.html</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\test\index.html">
+ <Link>Resources\dashboard-ui\bower_components\iron-flex-layout\test\index.html</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout-classes.html">
+ <Link>Resources\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout-classes.html</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout.html">
+ <Link>Resources\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout.html</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-form-element-behavior\.bower.json">
<Link>Resources\dashboard-ui\bower_components\iron-form-element-behavior\.bower.json</Link>
</BundleResource>
@@ -2495,6 +2522,12 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-resizable-behavior\.gitignore">
<Link>Resources\dashboard-ui\bower_components\iron-resizable-behavior\.gitignore</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-resizable-behavior\.travis.yml">
+ <Link>Resources\dashboard-ui\bower_components\iron-resizable-behavior\.travis.yml</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-resizable-behavior\CONTRIBUTING.md">
+ <Link>Resources\dashboard-ui\bower_components\iron-resizable-behavior\CONTRIBUTING.md</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-resizable-behavior\README.md">
<Link>Resources\dashboard-ui\bower_components\iron-resizable-behavior\README.md</Link>
</BundleResource>
@@ -2651,50 +2684,17 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.bower.json">
<Link>Resources\dashboard-ui\bower_components\jquery\.bower.json</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.editorconfig">
- <Link>Resources\dashboard-ui\bower_components\jquery\.editorconfig</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.gitattributes">
- <Link>Resources\dashboard-ui\bower_components\jquery\.gitattributes</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.gitignore">
- <Link>Resources\dashboard-ui\bower_components\jquery\.gitignore</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.jscsrc">
- <Link>Resources\dashboard-ui\bower_components\jquery\.jscsrc</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.jshintignore">
- <Link>Resources\dashboard-ui\bower_components\jquery\.jshintignore</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.jshintrc">
- <Link>Resources\dashboard-ui\bower_components\jquery\.jshintrc</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.mailmap">
- <Link>Resources\dashboard-ui\bower_components\jquery\.mailmap</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.npmignore">
- <Link>Resources\dashboard-ui\bower_components\jquery\.npmignore</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.travis.yml">
- <Link>Resources\dashboard-ui\bower_components\jquery\.travis.yml</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\AUTHORS.txt">
<Link>Resources\dashboard-ui\bower_components\jquery\AUTHORS.txt</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\CONTRIBUTING.md">
- <Link>Resources\dashboard-ui\bower_components\jquery\CONTRIBUTING.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\Gruntfile.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\Gruntfile.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\LICENSE.txt">
<Link>Resources\dashboard-ui\bower_components\jquery\LICENSE.txt</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\README.md">
<Link>Resources\dashboard-ui\bower_components\jquery\README.md</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\package.json">
- <Link>Resources\dashboard-ui\bower_components\jquery\package.json</Link>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\bower.json">
+ <Link>Resources\dashboard-ui\bower_components\jquery\bower.json</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.js">
<Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.js</Link>
@@ -2705,44 +2705,14 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.min.map">
<Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.min.map</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\npo\npo.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\npo\npo.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit\LICENSE.txt">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\qunit\LICENSE.txt</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit\MIT-LICENSE.txt">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\qunit\MIT-LICENSE.txt</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit\qunit.css">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.css</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit\qunit.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit-assert-step\MIT-LICENSE.txt">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\MIT-LICENSE.txt</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit-assert-step\qunit-assert-step.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\qunit-assert-step.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\requirejs\require.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\requirejs\require.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sinon\sinon-1.14.1.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\sinon\sinon-1.14.1.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sizzle\LICENSE.txt">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\sizzle\LICENSE.txt</Link>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.slim.js">
+ <Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.slim.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.js</Link>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.js">
+ <Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.map">
- <Link>Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.map</Link>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.map">
+ <Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.map</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\.jshintrc">
<Link>Resources\dashboard-ui\bower_components\jquery\src\.jshintrc</Link>
@@ -2810,6 +2780,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\serialize.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\serialize.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\support.js">
+ <Link>Resources\dashboard-ui\bower_components\jquery\src\support.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\traversing.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\traversing.js</Link>
</BundleResource>
@@ -2849,6 +2822,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\attributes\val.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\attributes\val.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\core\DOMEval.js">
+ <Link>Resources\dashboard-ui\bower_components\jquery\src\core\DOMEval.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\core\access.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\core\access.js</Link>
</BundleResource>
@@ -2888,12 +2864,24 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\data\Data.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\data\Data.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\data\accepts.js">
+ <Link>Resources\dashboard-ui\bower_components\jquery\src\data\accepts.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\data\support.js">
+ <Link>Resources\dashboard-ui\bower_components\jquery\src\data\support.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\deferred\exceptionHook.js">
+ <Link>Resources\dashboard-ui\bower_components\jquery\src\deferred\exceptionHook.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\effects\Tween.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\effects\Tween.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\effects\animatedSelector.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\effects\animatedSelector.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\effects\support.js">
+ <Link>Resources\dashboard-ui\bower_components\jquery\src\effects\support.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\event\ajax.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\event\ajax.js</Link>
</BundleResource>
@@ -2921,6 +2909,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\manipulation\buildFragment.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\manipulation\buildFragment.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\manipulation\createSafeFragment.js">
+ <Link>Resources\dashboard-ui\bower_components\jquery\src\manipulation\createSafeFragment.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\manipulation\getAll.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\manipulation\getAll.js</Link>
</BundleResource>
@@ -2939,366 +2930,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\traversing\findFilter.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\traversing\findFilter.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\.jshintrc">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\.jshintrc</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\delegatetest.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\delegatetest.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\hovertest.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\hovertest.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\index.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\jquery.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\jquery.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\localfile.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\localfile.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\networkerror.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\networkerror.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\promises_aplus_adapter.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\promises_aplus_adapter.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\readywait.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\readywait.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\xhtml.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\xhtml.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\1x1.jpg">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\1x1.jpg</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\atom+xml.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\atom+xml.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\badcall.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\badcall.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\badjson.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\badjson.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\cleanScript.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\cleanScript.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\dashboard.xml">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\dashboard.xml</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\echoData.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\echoData.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\echoQuery.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\echoQuery.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\errorWithJSON.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\errorWithJSON.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\errorWithText.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\errorWithText.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\etag.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\etag.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\headers.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\headers.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\if_modified_since.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\if_modified_since.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\iframe.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\iframe.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\jquery-1.9.1.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\jquery-1.9.1.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\json.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\json.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\json_obj.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\json_obj.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\jsonp.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\jsonp.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\name.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\name.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\name.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\name.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\nocontent.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\nocontent.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\params_html.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\params_html.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\readywaitasset.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\readywaitasset.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\readywaitloader.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\readywaitloader.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\script.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\script.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\statusText.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\statusText.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\test.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\test.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\test.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\test.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\test2.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\test2.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\test3.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\test3.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\testbar.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\testbar.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\testinit.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\testinit.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\testrunner.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\testrunner.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\testsuite.css">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\testsuite.css</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\text.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\text.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\with_fries.xml">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\with_fries.xml</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\with_fries_over_jsonp.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\with_fries_over_jsonp.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\content-type.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\content-type.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\evalScript.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\evalScript.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\method.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\method.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\onunload.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\onunload.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\unreleasedXHR.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\unreleasedXHR.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\aliased.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\aliased.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\cc_on.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\cc_on.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\dont_return.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\dont_return.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\dynamic_ready.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\dynamic_ready.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\onready.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\onready.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\css\cssWidthBeforeDocReady.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\css\cssWidthBeforeDocReady.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\data\dataAttrs.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\data\dataAttrs.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\dimensions\documentLarge.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\dimensions\documentLarge.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\focusElem.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\focusElem.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\focusinCrossFrame.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\focusinCrossFrame.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\interactiveReady.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\interactiveReady.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\longLoadScript.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\longLoadScript.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\onbeforeunload.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\onbeforeunload.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\promiseReady.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\promiseReady.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\syncReady.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\syncReady.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\triggerunload.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\triggerunload.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\manipulation\iframe-denied.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\manipulation\iframe-denied.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\absolute.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\absolute.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\body.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\body.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\fixed.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\fixed.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\relative.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\relative.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\scroll.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\scroll.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\static.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\static.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\table.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\table.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\selector\html5_selector.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\selector\html5_selector.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\selector\sizzle_cache.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\selector\sizzle_cache.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\bodyBackground.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\bodyBackground.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\csp-clean.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-clean.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\csp-log.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-log.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\csp.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\csp.php">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.php</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\getComputedSupport.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\getComputedSupport.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\gh-1764-fullscreen.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\integration\gh-1764-fullscreen.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\gh-2343-ie-radio-click.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\integration\gh-2343-ie-radio-click.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.css">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.css</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.html">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\.jshintrc">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\.jshintrc</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_missing.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_missing.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_passed.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_passed.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_present_originally.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_present_originally.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_native_symbol.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_native_symbol.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_symbol_polyfill.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_symbol_polyfill.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_global_not_created.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_global_not_created.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_iterability_es6.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_iterability_es6.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_jquery.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_jquery.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\ajax.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\ajax.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\attributes.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\attributes.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\basic.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\basic.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\callbacks.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\callbacks.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\core.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\core.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\css.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\css.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\data.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\data.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\deferred.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\deferred.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\deprecated.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\deprecated.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\dimensions.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\dimensions.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\effects.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\effects.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\event.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\event.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\exports.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\exports.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\manipulation.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\manipulation.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\offset.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\offset.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\queue.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\queue.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\ready.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\ready.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\selector.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\selector.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\serialize.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\serialize.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\support.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\support.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\traversing.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\traversing.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\wrap.js">
- <Link>Resources\dashboard-ui\bower_components\jquery\test\unit\wrap.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jstree\.bower.json">
<Link>Resources\dashboard-ui\bower_components\jstree\.bower.json</Link>
</BundleResource>
@@ -8774,21 +8405,21 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\devices\ios\ios.css">
<Link>Resources\dashboard-ui\devices\ios\ios.css</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\devices\windowsphone\wp.css">
+ <Link>Resources\dashboard-ui\devices\windowsphone\wp.css</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\files\dummy.mp4">
<Link>Resources\dashboard-ui\files\dummy.mp4</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\legacy\buttonenabled.js">
<Link>Resources\dashboard-ui\legacy\buttonenabled.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\legacy\deferred.js">
- <Link>Resources\dashboard-ui\legacy\deferred.js</Link>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\legacy\dashboard.js">
+ <Link>Resources\dashboard-ui\legacy\dashboard.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\aboutpage.js">
<Link>Resources\dashboard-ui\scripts\aboutpage.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\actionsheet.js">
- <Link>Resources\dashboard-ui\scripts\actionsheet.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\addpluginpage.js">
<Link>Resources\dashboard-ui\scripts\addpluginpage.js</Link>
</BundleResource>
@@ -9116,6 +8747,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\photos.js">
<Link>Resources\dashboard-ui\scripts\photos.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\pin.js">
+ <Link>Resources\dashboard-ui\scripts\pin.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\playbackconfiguration.js">
<Link>Resources\dashboard-ui\scripts\playbackconfiguration.js</Link>
</BundleResource>
@@ -9929,8 +9563,11 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\thirdparty\social-share-kit-1.0.4\dist\js\social-share-kit.min.js">
<Link>Resources\dashboard-ui\thirdparty\social-share-kit-1.0.4\dist\js\social-share-kit.min.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\textprocessor-en-us.js">
- <Link>Resources\dashboard-ui\voice\textprocessor-en-us.js</Link>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\Readme.md">
+ <Link>Resources\dashboard-ui\voice\Readme.md</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\grammarprocessor.js">
+ <Link>Resources\dashboard-ui\voice\grammarprocessor.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\voice.css">
<Link>Resources\dashboard-ui\voice\voice.css</Link>
@@ -9938,5 +9575,38 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\voice.js">
<Link>Resources\dashboard-ui\voice\voice.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\voicecommands.js">
+ <Link>Resources\dashboard-ui\voice\voicecommands.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\voicedialog.js">
+ <Link>Resources\dashboard-ui\voice\voicedialog.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\controlcommands.js">
+ <Link>Resources\dashboard-ui\voice\commands\controlcommands.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\disablecommands.js">
+ <Link>Resources\dashboard-ui\voice\commands\disablecommands.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\enablecommands.js">
+ <Link>Resources\dashboard-ui\voice\commands\enablecommands.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\playcommands.js">
+ <Link>Resources\dashboard-ui\voice\commands\playcommands.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\searchcommands.js">
+ <Link>Resources\dashboard-ui\voice\commands\searchcommands.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\showcommands.js">
+ <Link>Resources\dashboard-ui\voice\commands\showcommands.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\togglecommands.js">
+ <Link>Resources\dashboard-ui\voice\commands\togglecommands.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\grammar\en-US.json">
+ <Link>Resources\dashboard-ui\voice\grammar\en-US.json</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\grammar\grammar.json">
+ <Link>Resources\dashboard-ui\voice\grammar\grammar.json</Link>
+ </BundleResource>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
index 9f36599fa..e3c4541f0 100644
--- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
+++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
@@ -54,7 +54,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
diff --git a/MediaBrowser.Server.Mono/packages.config b/MediaBrowser.Server.Mono/packages.config
index 2956d69c6..99bcc7f4b 100644
--- a/MediaBrowser.Server.Mono/packages.config
+++ b/MediaBrowser.Server.Mono/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index e61a64646..a54380850 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -490,7 +490,7 @@ namespace MediaBrowser.Server.Startup.Common
ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LogManager.GetLogger("ChannelManager"), ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager);
RegisterSingleInstance(ChannelManager);
- MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, LogManager.GetLogger("MediaSourceManager"), JsonSerializer, FileSystemManager);
+ MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, LogManager.GetLogger("MediaSourceManager"), JsonSerializer, FileSystemManager, UserDataManager);
RegisterSingleInstance(MediaSourceManager);
SessionManager = new SessionManager(UserDataManager, LogManager.GetLogger("SessionManager"), UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager);
diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
index a4028d5b0..dbbd054a8 100644
--- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
+++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
@@ -33,7 +33,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
diff --git a/MediaBrowser.Server.Startup.Common/packages.config b/MediaBrowser.Server.Startup.Common/packages.config
index 2956d69c6..99bcc7f4b 100644
--- a/MediaBrowser.Server.Startup.Common/packages.config
+++ b/MediaBrowser.Server.Startup.Common/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
index 80e56d6e1..d8eed80bd 100644
--- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
+++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
@@ -63,7 +63,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="ImageMagickSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config
index be12bcd5c..fd2f2c806 100644
--- a/MediaBrowser.ServerApplication/packages.config
+++ b/MediaBrowser.ServerApplication/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="ImageMagickSharp" version="1.0.0.18" targetFramework="net45" />
<package id="MediaBrowser.IsoMounting" version="3.0.69" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 227026154..788825a7b 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -345,7 +345,6 @@ namespace MediaBrowser.WebDashboard.Api
DeleteFoldersByName(bowerPath, "grunt");
DeleteFoldersByName(bowerPath, "rollups");
- _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "jquery", "external"), true);
_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "jquery", "src"), true);
DeleteCryptoFiles(Path.Combine(bowerPath, "cryptojslib", "components"));
diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
index 67eb3d53b..c3db09457 100644
--- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs
+++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
@@ -354,7 +354,7 @@ namespace MediaBrowser.WebDashboard.Api
if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
{
- sb.Append("<meta http-equiv=\"Content-Security-Policy\" content=\"default-src * 'unsafe-inline' 'unsafe-eval'\">");
+ sb.Append("<meta http-equiv=\"Content-Security-Policy\" content=\"default-src * 'unsafe-inline' 'unsafe-eval' data:;\">");
}
sb.Append("<link rel=\"manifest\" href=\"manifest.json\">");
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 9de20cb39..b8bb397fc 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -49,7 +49,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="Patterns.Logging">
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
@@ -140,6 +140,9 @@
<Content Include="dashboard-ui\components\remotecontrolautoplay.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\devices\windowsphone\wp.css">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\legacy\buttonenabled.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -254,9 +257,9 @@
<Content Include="dashboard-ui\favorites.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <None Include="dashboard-ui\legacy\deferred.js">
+ <Content Include="dashboard-ui\legacy\dashboard.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
+ </Content>
<Content Include="dashboard-ui\livetvguideprovider.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -278,9 +281,6 @@
<Content Include="dashboard-ui\robots.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\actionsheet.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\scripts\globalize.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -460,12 +460,6 @@
<Content Include="dashboard-ui\components\tvproviders\schedulesdirect.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\voice\textprocessor-en-us.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\voice\voice.css">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\dashboardhosting.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -487,9 +481,6 @@
<Content Include="dashboard-ui\photos.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\appsettings.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\scripts\dashboardhosting.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -544,9 +535,6 @@
<Content Include="dashboard-ui\scripts\userpassword.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\voice\voice.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\scripts\wizardagreement.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -1066,334 +1054,70 @@
<Content Include="dashboard-ui\scripts\wizardsettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\action-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\action-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\alert-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\alert-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-d-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-d-l-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-d-l-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-d-r-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-d-r-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-d-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-l-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-l-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-r-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-r-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-u-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-u-l-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-u-l-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-u-r-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-u-r-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\arrow-u-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\audio-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\audio-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\back-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\back-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\bars-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\bars-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\bullets-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\bullets-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\calendar-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\calendar-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\camera-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\camera-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\carat-d-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\carat-d-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\carat-l-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\carat-l-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\carat-r-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\carat-r-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\carat-u-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\carat-u-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\check-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\check-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\clock-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\clock-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\cloud-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\cloud-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\comment-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\comment-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\delete-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\delete-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\edit-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\edit-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\eye-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\eye-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\forbidden-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\forbidden-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\forward-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\forward-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\gear-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\gear-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\grid-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\grid-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\heart-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\heart-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\home-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\home-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\info-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\info-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\location-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\location-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\lock-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\lock-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\mail-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\mail-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\minus-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\minus-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\navigation-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\navigation-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\phone-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\phone-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\plus-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\plus-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\power-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\power-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\recycle-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\recycle-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\refresh-black.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\refresh-white.svg">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\search-black.svg">
+ <Content Include="dashboard-ui\livetv.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\search-white.svg">
+ <Content Include="dashboard-ui\thirdparty\jstree\themes\default\32px.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\shop-black.svg">
+ <Content Include="dashboard-ui\thirdparty\jstree\themes\default\40px.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\shop-white.svg">
+ <Content Include="dashboard-ui\thirdparty\jstree\themes\default\style.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\star-black.svg">
+ <Content Include="dashboard-ui\thirdparty\jstree\themes\default\style.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\star-white.svg">
+ <Content Include="dashboard-ui\thirdparty\jstree\themes\default\throbber.gif">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\tag-black.svg">
+ <Content Include="dashboard-ui\userlibraryaccess.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\tag-white.svg">
+ <Content Include="dashboard-ui\usernew.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\user-black.svg">
+ <Content Include="dashboard-ui\userparentalcontrol.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\user-white.svg">
+ <Content Include="dashboard-ui\userpassword.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\video-black.svg">
+ <Content Include="dashboard-ui\voice\commands\controlcommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\images\icons-svg\video-white.svg">
+ <Content Include="dashboard-ui\voice\commands\disablecommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\livetv.html">
+ <Content Include="dashboard-ui\voice\commands\enablecommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jstree\themes\default\32px.png">
+ <Content Include="dashboard-ui\voice\commands\playcommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jstree\themes\default\40px.png">
+ <Content Include="dashboard-ui\voice\commands\searchcommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jstree\themes\default\style.css">
+ <Content Include="dashboard-ui\voice\commands\showcommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jstree\themes\default\style.min.css">
+ <Content Include="dashboard-ui\voice\commands\togglecommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jstree\themes\default\throbber.gif">
+ <Content Include="dashboard-ui\voice\grammarprocessor.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\userlibraryaccess.html">
+ <Content Include="dashboard-ui\voice\voicedialog.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\usernew.html">
+ <Content Include="dashboard-ui\voice\voice.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\userparentalcontrol.html">
+ <Content Include="dashboard-ui\voice\voice.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\userpassword.html">
+ <Content Include="dashboard-ui\voice\voicecommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\wizardagreement.html">
@@ -1963,247 +1687,124 @@
<None Include="dashboard-ui\css\fonts\roboto\VvXUGKZXbHtX_S_VCTLpGhTbgVql8nDJpwnrE27mub0.woff2">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
- <Content Include="dashboard-ui\strings\html\ar.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\html\bg-BG.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\html\ca.json">
+ <Content Include="dashboard-ui\strings\ar.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\cs.json">
+ <Content Include="dashboard-ui\strings\bg-BG.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\da.json">
+ <Content Include="dashboard-ui\strings\ca.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\de.json">
+ <Content Include="dashboard-ui\strings\cs.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\el.json">
+ <Content Include="dashboard-ui\strings\da.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\en-GB.json">
+ <Content Include="dashboard-ui\strings\de.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\en-US.json">
+ <Content Include="dashboard-ui\strings\el.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\es-AR.json">
+ <Content Include="dashboard-ui\strings\en-GB.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\es-MX.json">
+ <Content Include="dashboard-ui\strings\en-US.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\es.json">
+ <Content Include="dashboard-ui\strings\es-AR.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\fi.json">
+ <Content Include="dashboard-ui\strings\es-MX.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\fr.json">
+ <Content Include="dashboard-ui\strings\es.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\gsw.json">
+ <Content Include="dashboard-ui\strings\fi.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\he.json">
+ <Content Include="dashboard-ui\strings\fr.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\hr.json">
+ <Content Include="dashboard-ui\strings\gsw.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\it.json">
+ <Content Include="dashboard-ui\strings\he.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\kk.json">
+ <Content Include="dashboard-ui\strings\hr.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\ko.json">
+ <Content Include="dashboard-ui\strings\it.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\ms.json">
+ <Content Include="dashboard-ui\strings\kk.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\nb.json">
+ <Content Include="dashboard-ui\strings\ko.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\nl.json">
+ <Content Include="dashboard-ui\strings\ms.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\pl.json">
+ <Content Include="dashboard-ui\strings\nb.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\pt-BR.json">
+ <Content Include="dashboard-ui\strings\nl.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\pt-PT.json">
+ <Content Include="dashboard-ui\strings\pl.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\ro.json">
+ <Content Include="dashboard-ui\strings\pt-BR.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\ru.json">
+ <Content Include="dashboard-ui\strings\pt-PT.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\server.json">
+ <Content Include="dashboard-ui\strings\ro.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\sl-SI.json">
+ <Content Include="dashboard-ui\strings\ru.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\sv.json">
+ <Content Include="dashboard-ui\strings\server.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\tr.json">
+ <Content Include="dashboard-ui\strings\sl-SI.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\uk.json">
+ <Content Include="dashboard-ui\strings\sv.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\vi.json">
+ <Content Include="dashboard-ui\strings\tr.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\zh-CN.json">
+ <Content Include="dashboard-ui\strings\uk.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\html\zh-TW.json">
+ <Content Include="dashboard-ui\strings\vi.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\javascript\ar.json">
+ <Content Include="dashboard-ui\strings\zh-CN.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\strings\javascript\be-BY.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\bg-BG.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\ca.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\cs.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\da.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\de.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\el.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\en-GB.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\en-US.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\es-AR.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\es-MX.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\es-VE.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\es.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\fi.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\fr.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\gsw.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\he.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\hr.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\hu.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\it.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\javascript.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\kk.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\ms.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\nb.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\nl.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\pl.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\pt-BR.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\pt-PT.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\ro.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\ru.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\sl-SI.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\sv.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\tr.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\uk.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\vi.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\zh-CN.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\strings\javascript\zh-TW.json">
+ <Content Include="dashboard-ui\strings\zh-TW.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="dashboard-ui\manifest.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
- <None Include="dashboard-ui\strings\html\hu.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="dashboard-ui\strings\html\id.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="dashboard-ui\strings\html\zh-HK.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- <None Include="dashboard-ui\strings\javascript\id.json">
+ <None Include="dashboard-ui\strings\hu.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
- <None Include="dashboard-ui\strings\javascript\ko.json">
+ <None Include="dashboard-ui\strings\id.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
- <None Include="dashboard-ui\strings\javascript\zh-HK.json">
+ <None Include="dashboard-ui\strings\zh-HK.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<Content Include="dashboard-ui\thirdparty\jquerymobile-1.4.5\jqm.table.js">
@@ -2226,6 +1827,15 @@
</None>
<None Include="dashboard-ui\thirdparty\social-share-kit-1.0.4\LICENSE" />
<None Include="dashboard-ui\thirdparty\social-share-kit-1.0.4\README.md" />
+ <None Include="dashboard-ui\voice\grammar\en-US.json">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Include="dashboard-ui\voice\grammar\grammar.json">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Include="dashboard-ui\voice\Readme.md">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config
index 128a2f162..f1f929f90 100644
--- a/MediaBrowser.WebDashboard/packages.config
+++ b/MediaBrowser.WebDashboard/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.249" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
<package id="WebMarkupMin.Core" version="1.0.1" targetFramework="net45" />
diff --git a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj
index 16b6ca995..73f4266fb 100644
--- a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj
+++ b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj
@@ -33,7 +33,7 @@
<ItemGroup>
<Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll</HintPath>
+ <HintPath>..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll</HintPath>
</Reference>
<Reference Include="Patterns.Logging">
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
diff --git a/MediaBrowser.XbmcMetadata/packages.config b/MediaBrowser.XbmcMetadata/packages.config
index 28556744d..0639208dd 100644
--- a/MediaBrowser.XbmcMetadata/packages.config
+++ b/MediaBrowser.XbmcMetadata/packages.config
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.7" targetFramework="net45" />
+ <package id="CommonIO" version="1.0.0.8" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.sln b/MediaBrowser.sln
index a9b5020ec..a55ae200a 100644
--- a/MediaBrowser.sln
+++ b/MediaBrowser.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
+# Visual Studio 14
+VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E64C-2A6F-4E35-9533-D53AC07C2CD1}"
EndProject
@@ -521,7 +521,4 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(Performance) = preSolution
- HasPerformanceSessions = true
- EndGlobalSection
EndGlobal
diff --git a/SharedVersion.cs b/SharedVersion.cs
index 033efbbd7..22f7fffd1 100644
--- a/SharedVersion.cs
+++ b/SharedVersion.cs
@@ -1,4 +1,4 @@
using System.Reflection;
//[assembly: AssemblyVersion("3.0.*")]
-[assembly: AssemblyVersion("3.0.5871")]
+[assembly: AssemblyVersion("3.0.5895")]