From 416a494b7866ca048b75728a54e8867ac61ab4cb Mon Sep 17 00:00:00 2001 From: Tim Hobbs Date: Mon, 7 Apr 2014 09:26:48 -0700 Subject: Additional cast params --- MediaBrowser.WebDashboard/ApiClient.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index c937c28ee..1a526d8a1 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -3846,7 +3846,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi * @param {String} userId * @param {String} itemId */ - self.reportPlaybackProgress = function (userId, itemId, mediaSourceId, positionTicks, isPaused, isMuted) { + self.reportPlaybackProgress = function (userId, itemId, mediaSourceId, params) { if (!userId) { throw new Error("null userId"); @@ -3862,25 +3862,29 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi var msgData = itemId; - msgData += "|" + (positionTicks == null ? "" : positionTicks); - msgData += "|" + (isPaused == null ? "" : isPaused); - msgData += "|" + (isMuted == null ? "" : isMuted); + msgData += "|" + (params.positionTicks == null ? "" : params.positionTicks); + msgData += "|" + (params.isPaused == null ? "" : params.isPaused); + msgData += "|" + (params.isMuted == null ? "" : params.isMuted); msgData += "|" + (mediaSourceId == null ? "" : mediaSourceId); + msgData += "|" + (params.audioStreamIndex == null ? "" : params.audioStreamIndex); + msgData += "|" + (params.subtitleStreamIndex == null ? "" : params.subtitleStreamIndex); + msgData += "|" + (params.volumeLevel == null ? "" : params.volumeLevel); + self.sendWebSocketMessage("PlaybackProgress", msgData); deferred.resolveWith(null, []); return deferred.promise(); } - var params = { - isPaused: isPaused, - isMuted: isMuted - }; + ////var params = { + //// isPaused: isPaused, + //// isMuted: isMuted + ////}; - if (positionTicks) { - params.positionTicks = positionTicks; - } + ////if (positionTicks) { + //// params.positionTicks = positionTicks; + ////} if (mediaSourceId) { params.mediaSourceId = mediaSourceId; -- cgit v1.2.3 From f64c7bb0c0702445a4dbcffdae55dcc36da6d931 Mon Sep 17 00:00:00 2001 From: Tim Hobbs Date: Mon, 7 Apr 2014 12:12:16 -0700 Subject: Undo some changes --- MediaBrowser.WebDashboard/ApiClient.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 1a526d8a1..74f989fc0 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -3846,7 +3846,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi * @param {String} userId * @param {String} itemId */ - self.reportPlaybackProgress = function (userId, itemId, mediaSourceId, params) { + self.reportPlaybackProgress = function (userId, itemId, mediaSourceId, positionTicks, isPaused, isMuted) { if (!userId) { throw new Error("null userId"); @@ -3867,9 +3867,9 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi msgData += "|" + (params.isMuted == null ? "" : params.isMuted); msgData += "|" + (mediaSourceId == null ? "" : mediaSourceId); - msgData += "|" + (params.audioStreamIndex == null ? "" : params.audioStreamIndex); - msgData += "|" + (params.subtitleStreamIndex == null ? "" : params.subtitleStreamIndex); - msgData += "|" + (params.volumeLevel == null ? "" : params.volumeLevel); + ////msgData += "|" + (params.audioStreamIndex == null ? "" : params.audioStreamIndex); + ////msgData += "|" + (params.subtitleStreamIndex == null ? "" : params.subtitleStreamIndex); + ////msgData += "|" + (params.volumeLevel == null ? "" : params.volumeLevel); self.sendWebSocketMessage("PlaybackProgress", msgData); @@ -3877,14 +3877,14 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi return deferred.promise(); } - ////var params = { - //// isPaused: isPaused, - //// isMuted: isMuted - ////}; + var params = { + isPaused: isPaused, + isMuted: isMuted + }; - ////if (positionTicks) { - //// params.positionTicks = positionTicks; - ////} + if (positionTicks) { + params.positionTicks = positionTicks; + } if (mediaSourceId) { params.mediaSourceId = mediaSourceId; -- cgit v1.2.3 From 655c7ccd139bdeecbdc24e551679e01c7db893ed Mon Sep 17 00:00:00 2001 From: Tim Hobbs Date: Tue, 8 Apr 2014 11:22:03 -0700 Subject: Enabled lazy load of poster images This should make initial load of the movies page a little more responsive for larger libraries. This can be used on any page loading images. --- MediaBrowser.WebDashboard/Api/DashboardService.cs | 1 + MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 +++ 2 files changed, 4 insertions(+) diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 6252a0346..dcfa7f2b6 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -419,6 +419,7 @@ namespace MediaBrowser.WebDashboard.Api { "scripts/all.js" + versionString, "thirdparty/jstree1.0/jquery.jstree.min.js", + "thirdparty/jquery.unveil-custom.js", "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js" }; diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 0ddb05577..5b219f451 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -653,6 +653,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 564b165b943b6a9e886d834eefd409fbc3bd5084 Mon Sep 17 00:00:00 2001 From: Tim Hobbs Date: Tue, 8 Apr 2014 11:25:45 -0700 Subject: Removed api client changes --- MediaBrowser.WebDashboard/ApiClient.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index dbc7ca6d7..6109faf91 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -3865,15 +3865,11 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi var msgData = itemId; - msgData += "|" + (params.positionTicks == null ? "" : params.positionTicks); - msgData += "|" + (params.isPaused == null ? "" : params.isPaused); - msgData += "|" + (params.isMuted == null ? "" : params.isMuted); + msgData += "|" + (positionTicks == null ? "" : params.positionTicks); + msgData += "|" + (isPaused == null ? "" : params.isPaused); + msgData += "|" + (isMuted == null ? "" : params.isMuted); msgData += "|" + (mediaSourceId == null ? "" : mediaSourceId); - ////msgData += "|" + (params.audioStreamIndex == null ? "" : params.audioStreamIndex); - ////msgData += "|" + (params.subtitleStreamIndex == null ? "" : params.subtitleStreamIndex); - ////msgData += "|" + (params.volumeLevel == null ? "" : params.volumeLevel); - self.sendWebSocketMessage("PlaybackProgress", msgData); deferred.resolveWith(null, []); -- cgit v1.2.3 From badbc5aa247cc704083d64e8cb0c424ab35a97a2 Mon Sep 17 00:00:00 2001 From: Tim Hobbs Date: Tue, 8 Apr 2014 11:28:25 -0700 Subject: Removed api client changes --- MediaBrowser.WebDashboard/ApiClient.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 6109faf91..a4c4d9783 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -3865,9 +3865,9 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi var msgData = itemId; - msgData += "|" + (positionTicks == null ? "" : params.positionTicks); - msgData += "|" + (isPaused == null ? "" : params.isPaused); - msgData += "|" + (isMuted == null ? "" : params.isMuted); + msgData += "|" + (positionTicks == null ? "" : positionTicks); + msgData += "|" + (isPaused == null ? "" : isPaused); + msgData += "|" + (isMuted == null ? "" : isMuted); msgData += "|" + (mediaSourceId == null ? "" : mediaSourceId); self.sendWebSocketMessage("PlaybackProgress", msgData); -- cgit v1.2.3 From 8f7d14eabb8c078071d2324a75cad193b9c37a0c Mon Sep 17 00:00:00 2001 From: 7illusions Date: Wed, 9 Apr 2014 12:11:53 +0200 Subject: PlayTo Error 500 fix --- MediaBrowser.Dlna/PlayTo/Device.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs index 1c243b6d3..054b7e136 100644 --- a/MediaBrowser.Dlna/PlayTo/Device.cs +++ b/MediaBrowser.Dlna/PlayTo/Device.cs @@ -337,7 +337,7 @@ namespace MediaBrowser.Dlna.PlayTo throw new InvalidOperationException("Unable to find service"); } - var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 1)) + var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, 1)) .ConfigureAwait(false); _lapsCount = GetLapsCount(); @@ -352,7 +352,7 @@ namespace MediaBrowser.Dlna.PlayTo var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); - var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 1)) + var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, 1)) .ConfigureAwait(false); await Task.Delay(50).ConfigureAwait(false); return true; @@ -366,7 +366,7 @@ namespace MediaBrowser.Dlna.PlayTo var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); - var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 1)) + var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, 1)) .ConfigureAwait(false); await Task.Delay(50).ConfigureAwait(false); -- cgit v1.2.3 From 4b206b9cac8fb3e34989aaa442a9389537c61d11 Mon Sep 17 00:00:00 2001 From: Tim Hobbs Date: Thu, 10 Apr 2014 04:12:48 -0700 Subject: Cast audio playback enhancements * Instant mix works, but not sure about managing the mix * Shuffle _should_ work, but same thing with mgmt Receiver page has also been enhanced for music playback. --- MediaBrowser.WebDashboard/Api/DashboardService.cs | 1 + MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 +++ 2 files changed, 4 insertions(+) diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index dcfa7f2b6..7ab489450 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -442,6 +442,7 @@ namespace MediaBrowser.WebDashboard.Api // jQuery + jQuery mobile await AppendResource(memoryStream, "thirdparty/jquery-2.0.3.min.js", newLineBytes).ConfigureAwait(false); await AppendResource(memoryStream, "thirdparty/jquerymobile-1.4.2/jquery.mobile-1.4.2.min.js", newLineBytes).ConfigureAwait(false); + await AppendResource(memoryStream, "thirdparty/jquery.ba-tinypubsub.min.js", newLineBytes).ConfigureAwait(false); await AppendLocalization(memoryStream).ConfigureAwait(false); await memoryStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 5b219f451..94265501c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -653,6 +653,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 3094868a83937d2f5c49b06abd53757ef304a7e2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 10 Apr 2014 11:06:54 -0400 Subject: beginning dlna server --- MediaBrowser.Api/Dlna/DlnaServerService.cs | 89 ++++ MediaBrowser.Api/Dlna/DlnaService.cs | 90 ++++ MediaBrowser.Api/DlnaService.cs | 90 ---- MediaBrowser.Api/MediaBrowser.Api.csproj | 3 +- MediaBrowser.Api/Playback/BaseStreamingService.cs | 20 +- MediaBrowser.Api/Playback/StreamState.cs | 3 + .../Networking/BaseNetworkManager.cs | 41 +- MediaBrowser.Controller/Dlna/ControlRequest.cs | 28 ++ MediaBrowser.Controller/Dlna/IDlnaManager.cs | 22 + MediaBrowser.Controller/LiveTv/LiveStreamInfo.cs | 21 +- .../MediaBrowser.Controller.csproj | 1 + MediaBrowser.Dlna/Common/Argument.cs | 12 + MediaBrowser.Dlna/Common/DeviceIcon.cs | 21 + MediaBrowser.Dlna/Common/DeviceService.cs | 21 + MediaBrowser.Dlna/Common/ServiceAction.cs | 21 + MediaBrowser.Dlna/Common/StateVariable.cs | 25 ++ MediaBrowser.Dlna/DlnaManager.cs | 26 +- MediaBrowser.Dlna/Images/logo-120.jpg | Bin 0 -> 6745 bytes MediaBrowser.Dlna/Images/logo-120.png | Bin 0 -> 4124 bytes MediaBrowser.Dlna/Images/logo-48.jpg | Bin 0 -> 2484 bytes MediaBrowser.Dlna/Images/logo-48.png | Bin 0 -> 1661 bytes MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 21 +- MediaBrowser.Dlna/PlayTo/Argument.cs | 29 -- MediaBrowser.Dlna/PlayTo/Device.cs | 18 +- MediaBrowser.Dlna/PlayTo/DeviceIcon.cs | 21 - MediaBrowser.Dlna/PlayTo/DeviceInfo.cs | 4 +- MediaBrowser.Dlna/PlayTo/DeviceService.cs | 30 -- MediaBrowser.Dlna/PlayTo/ServiceAction.cs | 34 -- MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs | 1 + MediaBrowser.Dlna/PlayTo/StateVariable.cs | 52 --- MediaBrowser.Dlna/PlayTo/TransportCommands.cs | 61 ++- .../Server/ContentDirectoryXmlBuilder.cs | 235 +++++++++++ MediaBrowser.Dlna/Server/ControlHandler.cs | 190 +++++++++ MediaBrowser.Dlna/Server/Datagram.cs | 65 +++ MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs | 179 ++++++++ MediaBrowser.Dlna/Server/DlnaServerEntryPoint.cs | 27 +- .../Server/ServiceActionListBuilder.cs | 209 ++++++++++ MediaBrowser.Dlna/Server/SsdpHandler.cs | 169 ++++++-- MediaBrowser.Dlna/Server/UpnpDevice.cs | 6 +- .../MediaBrowser.MediaEncoding.csproj | 6 +- MediaBrowser.Model/Dlna/DeviceProfile.cs | 1 + MediaBrowser.Mono.sln | 26 +- MediaBrowser.Mono.userprefs | 2 +- .../Music/LastfmArtistProvider.cs | 5 +- .../Library/SearchEngine.cs | 16 +- .../Localization/JavaScript/ar.json | 31 +- .../Localization/JavaScript/ca.json | 30 ++ .../Localization/JavaScript/cs.json | 31 +- .../Localization/JavaScript/de.json | 31 +- .../Localization/JavaScript/el.json | 31 +- .../Localization/JavaScript/en_US.json | 31 +- .../Localization/JavaScript/es.json | 31 +- .../Localization/JavaScript/es_MX.json | 31 +- .../Localization/JavaScript/fr.json | 31 +- .../Localization/JavaScript/he.json | 31 +- .../Localization/JavaScript/it.json | 31 +- .../Localization/JavaScript/ms.json | 30 ++ .../Localization/JavaScript/nb.json | 31 +- .../Localization/JavaScript/nl.json | 31 +- .../Localization/JavaScript/pt_BR.json | 31 +- .../Localization/JavaScript/pt_PT.json | 31 +- .../Localization/JavaScript/ru.json | 31 +- .../Localization/JavaScript/sv.json | 31 +- .../Localization/JavaScript/zh_TW.json | 31 +- .../Localization/Server/ar.json | 452 ++++++++++++++++++++- .../Localization/Server/ca.json | 451 ++++++++++++++++++++ .../Localization/Server/cs.json | 452 ++++++++++++++++++++- .../Localization/Server/de.json | 452 ++++++++++++++++++++- .../Localization/Server/el.json | 452 ++++++++++++++++++++- .../Localization/Server/en_GB.json | 452 ++++++++++++++++++++- .../Localization/Server/en_US.json | 452 ++++++++++++++++++++- .../Localization/Server/es.json | 452 ++++++++++++++++++++- .../Localization/Server/es_MX.json | 452 ++++++++++++++++++++- .../Localization/Server/fr.json | 452 ++++++++++++++++++++- .../Localization/Server/he.json | 452 ++++++++++++++++++++- .../Localization/Server/it.json | 452 ++++++++++++++++++++- .../Localization/Server/ms.json | 451 ++++++++++++++++++++ .../Localization/Server/nb.json | 452 ++++++++++++++++++++- .../Localization/Server/nl.json | 452 ++++++++++++++++++++- .../Localization/Server/pt_BR.json | 452 ++++++++++++++++++++- .../Localization/Server/pt_PT.json | 452 ++++++++++++++++++++- .../Localization/Server/ru.json | 452 ++++++++++++++++++++- .../Localization/Server/sv.json | 452 ++++++++++++++++++++- .../Localization/Server/zh_TW.json | 452 ++++++++++++++++++++- .../MediaBrowser.Server.Implementations.csproj | 4 + .../Udp/UdpServer.cs | 3 +- .../MediaBrowser.Server.Mono.csproj | 6 +- MediaBrowser.Server.Mono/Program.cs | 17 +- 88 files changed, 11221 insertions(+), 375 deletions(-) create mode 100644 MediaBrowser.Api/Dlna/DlnaServerService.cs create mode 100644 MediaBrowser.Api/Dlna/DlnaService.cs delete mode 100644 MediaBrowser.Api/DlnaService.cs create mode 100644 MediaBrowser.Controller/Dlna/ControlRequest.cs create mode 100644 MediaBrowser.Dlna/Common/Argument.cs create mode 100644 MediaBrowser.Dlna/Common/DeviceIcon.cs create mode 100644 MediaBrowser.Dlna/Common/DeviceService.cs create mode 100644 MediaBrowser.Dlna/Common/ServiceAction.cs create mode 100644 MediaBrowser.Dlna/Common/StateVariable.cs create mode 100644 MediaBrowser.Dlna/Images/logo-120.jpg create mode 100644 MediaBrowser.Dlna/Images/logo-120.png create mode 100644 MediaBrowser.Dlna/Images/logo-48.jpg create mode 100644 MediaBrowser.Dlna/Images/logo-48.png delete mode 100644 MediaBrowser.Dlna/PlayTo/Argument.cs delete mode 100644 MediaBrowser.Dlna/PlayTo/DeviceIcon.cs delete mode 100644 MediaBrowser.Dlna/PlayTo/DeviceService.cs delete mode 100644 MediaBrowser.Dlna/PlayTo/ServiceAction.cs delete mode 100644 MediaBrowser.Dlna/PlayTo/StateVariable.cs create mode 100644 MediaBrowser.Dlna/Server/ContentDirectoryXmlBuilder.cs create mode 100644 MediaBrowser.Dlna/Server/ControlHandler.cs create mode 100644 MediaBrowser.Dlna/Server/Datagram.cs create mode 100644 MediaBrowser.Dlna/Server/DescriptionXmlBuilder.cs create mode 100644 MediaBrowser.Dlna/Server/ServiceActionListBuilder.cs create mode 100644 MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json create mode 100644 MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json create mode 100644 MediaBrowser.Server.Implementations/Localization/Server/ca.json create mode 100644 MediaBrowser.Server.Implementations/Localization/Server/ms.json diff --git a/MediaBrowser.Api/Dlna/DlnaServerService.cs b/MediaBrowser.Api/Dlna/DlnaServerService.cs new file mode 100644 index 000000000..922c67aa2 --- /dev/null +++ b/MediaBrowser.Api/Dlna/DlnaServerService.cs @@ -0,0 +1,89 @@ +using MediaBrowser.Controller.Dlna; +using ServiceStack; +using ServiceStack.Web; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace MediaBrowser.Api.Dlna +{ + [Route("/Dlna/{UuId}/description.xml", "GET", Summary = "Gets dlna server info")] + [Route("/Dlna/{UuId}/description", "GET", Summary = "Gets dlna server info")] + public class GetDescriptionXml + { + [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")] + public string UuId { get; set; } + } + + [Route("/Dlna/{UuId}/contentdirectory.xml", "GET", Summary = "Gets dlna content directory xml")] + [Route("/Dlna/{UuId}/contentdirectory", "GET", Summary = "Gets the content directory xml")] + public class GetContentDirectory + { + [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")] + public string UuId { get; set; } + } + + [Route("/Dlna/{UuId}/control", "POST", Summary = "Processes a control request")] + public class ProcessControlRequest : IRequiresRequestStream + { + [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")] + public string UuId { get; set; } + + public Stream RequestStream { get; set; } + } + + public class DlnaServerService : BaseApiService + { + private readonly IDlnaManager _dlnaManager; + + public DlnaServerService(IDlnaManager dlnaManager) + { + _dlnaManager = dlnaManager; + } + + public object Get(GetDescriptionXml request) + { + var xml = _dlnaManager.GetServerDescriptionXml(GetRequestHeaders(), request.UuId); + + return ResultFactory.GetResult(xml, "text/xml"); + } + + public object Get(GetContentDirectory request) + { + var xml = _dlnaManager.GetContentDirectoryXml(GetRequestHeaders()); + + return ResultFactory.GetResult(xml, "text/xml"); + } + + public object Post(ProcessControlRequest request) + { + var response = PostAsync(request).Result; + + return ResultFactory.GetResult(response.Xml, "text/xml"); + } + + private async Task PostAsync(ProcessControlRequest request) + { + using (var reader = new StreamReader(request.RequestStream)) + { + return _dlnaManager.ProcessControlRequest(new ControlRequest + { + Headers = GetRequestHeaders(), + InputXml = await reader.ReadToEndAsync().ConfigureAwait(false) + }); + } + } + + private IDictionary GetRequestHeaders() + { + var headers = new Dictionary(); + + foreach (var key in Request.Headers.AllKeys) + { + headers[key] = Request.Headers[key]; + } + + return headers; + } + } +} diff --git a/MediaBrowser.Api/Dlna/DlnaService.cs b/MediaBrowser.Api/Dlna/DlnaService.cs new file mode 100644 index 000000000..9e6ca3aea --- /dev/null +++ b/MediaBrowser.Api/Dlna/DlnaService.cs @@ -0,0 +1,90 @@ +using MediaBrowser.Controller.Dlna; +using MediaBrowser.Model.Dlna; +using ServiceStack; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Api.Dlna +{ + [Route("/Dlna/ProfileInfos", "GET", Summary = "Gets a list of profiles")] + public class GetProfileInfos : IReturn> + { + } + + [Route("/Dlna/Profiles/{Id}", "DELETE", Summary = "Deletes a profile")] + public class DeleteProfile : IReturnVoid + { + [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] + public string Id { get; set; } + } + + [Route("/Dlna/Profiles/Default", "GET", Summary = "Gets the default profile")] + public class GetDefaultProfile : IReturn + { + } + + [Route("/Dlna/Profiles/{Id}", "GET", Summary = "Gets a single profile")] + public class GetProfile : IReturn + { + [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + + [Route("/Dlna/Profiles/{ProfileId}", "POST", Summary = "Updates a profile")] + public class UpdateProfile : DeviceProfile, IReturnVoid + { + [ApiMember(Name = "ProfileId", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string ProfileId { get; set; } + } + + [Route("/Dlna/Profiles", "POST", Summary = "Creates a profile")] + public class CreateProfile : DeviceProfile, IReturnVoid + { + } + + public class DlnaService : BaseApiService + { + private readonly IDlnaManager _dlnaManager; + + public DlnaService(IDlnaManager dlnaManager) + { + _dlnaManager = dlnaManager; + } + + public object Get(GetProfileInfos request) + { + var result = _dlnaManager.GetProfileInfos().ToList(); + + return ToOptimizedResult(result); + } + + public object Get(GetProfile request) + { + var result = _dlnaManager.GetProfile(request.Id); + + return ToOptimizedResult(result); + } + + public object Get(GetDefaultProfile request) + { + var result = _dlnaManager.GetDefaultProfile(); + + return ToOptimizedResult(result); + } + + public void Delete(DeleteProfile request) + { + _dlnaManager.DeleteProfile(request.Id); + } + + public void Post(UpdateProfile request) + { + _dlnaManager.UpdateProfile(request); + } + + public void Post(CreateProfile request) + { + _dlnaManager.CreateProfile(request); + } + } +} diff --git a/MediaBrowser.Api/DlnaService.cs b/MediaBrowser.Api/DlnaService.cs deleted file mode 100644 index 792a7ff43..000000000 --- a/MediaBrowser.Api/DlnaService.cs +++ /dev/null @@ -1,90 +0,0 @@ -using MediaBrowser.Controller.Dlna; -using MediaBrowser.Model.Dlna; -using ServiceStack; -using System.Collections.Generic; -using System.Linq; - -namespace MediaBrowser.Api -{ - [Route("/Dlna/ProfileInfos", "GET", Summary = "Gets a list of profiles")] - public class GetProfileInfos : IReturn> - { - } - - [Route("/Dlna/Profiles/{Id}", "DELETE", Summary = "Deletes a profile")] - public class DeleteProfile : IReturnVoid - { - [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] - public string Id { get; set; } - } - - [Route("/Dlna/Profiles/Default", "GET", Summary = "Gets the default profile")] - public class GetDefaultProfile : IReturn - { - } - - [Route("/Dlna/Profiles/{Id}", "GET", Summary = "Gets a single profile")] - public class GetProfile : IReturn - { - [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] - public string Id { get; set; } - } - - [Route("/Dlna/Profiles/{ProfileId}", "POST", Summary = "Updates a profile")] - public class UpdateProfile : DeviceProfile, IReturnVoid - { - [ApiMember(Name = "ProfileId", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] - public string ProfileId { get; set; } - } - - [Route("/Dlna/Profiles", "POST", Summary = "Creates a profile")] - public class CreateProfile : DeviceProfile, IReturnVoid - { - } - - public class DlnaService : BaseApiService - { - private readonly IDlnaManager _dlnaManager; - - public DlnaService(IDlnaManager dlnaManager) - { - _dlnaManager = dlnaManager; - } - - public object Get(GetProfileInfos request) - { - var result = _dlnaManager.GetProfileInfos().ToList(); - - return ToOptimizedResult(result); - } - - public object Get(GetProfile request) - { - var result = _dlnaManager.GetProfile(request.Id); - - return ToOptimizedResult(result); - } - - public object Get(GetDefaultProfile request) - { - var result = _dlnaManager.GetDefaultProfile(); - - return ToOptimizedResult(result); - } - - public void Delete(DeleteProfile request) - { - _dlnaManager.DeleteProfile(request.Id); - } - - public void Post(UpdateProfile request) - { - _dlnaManager.UpdateProfile(request); - } - - public void Post(CreateProfile request) - { - _dlnaManager.CreateProfile(request); - } - } -} diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index c03eddf99..edbae3903 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -66,7 +66,8 @@ Properties\SharedVersion.cs - + + diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index bb55b893a..4b0406cde 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1341,6 +1341,12 @@ namespace MediaBrowser.Api.Playback RequestedUrl = url }; + if (!string.IsNullOrWhiteSpace(request.AudioCodec)) + { + state.SupportedAudioCodecs = request.AudioCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + state.Request.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(); + } + var item = string.IsNullOrEmpty(request.MediaSourceId) ? DtoService.GetItemByDtoId(request.Id) : DtoService.GetItemByDtoId(request.MediaSourceId); @@ -1492,10 +1498,10 @@ namespace MediaBrowser.Api.Playback videoRequest.VideoCodec = "copy"; } - //if (state.AudioStream != null && CanStreamCopyAudio(request, state.AudioStream)) - //{ - // request.AudioCodec = "copy"; - //} + if (state.AudioStream != null && CanStreamCopyAudio(request, state.AudioStream, state.SupportedAudioCodecs)) + { + request.AudioCodec = "copy"; + } } return state; @@ -1587,10 +1593,10 @@ namespace MediaBrowser.Api.Playback return SupportsAutomaticVideoStreamCopy; } - private bool CanStreamCopyAudio(StreamRequest request, MediaStream audioStream) + private bool CanStreamCopyAudio(StreamRequest request, MediaStream audioStream, List supportedAudioCodecs) { // Source and target codecs must match - if (string.IsNullOrEmpty(request.AudioCodec) || !string.Equals(request.AudioCodec, audioStream.Codec, StringComparison.OrdinalIgnoreCase)) + if (string.IsNullOrEmpty(audioStream.Codec) || !supportedAudioCodecs.Contains(audioStream.Codec, StringComparer.OrdinalIgnoreCase)) { return false; } @@ -1623,7 +1629,7 @@ namespace MediaBrowser.Api.Playback } } - return SupportsAutomaticVideoStreamCopy; + return true; } protected virtual bool SupportsAutomaticVideoStreamCopy diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index ce7d79917..e41f29663 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -67,10 +67,13 @@ namespace MediaBrowser.Api.Playback public string AudioSync = "1"; public string VideoSync = "vfr"; + public List SupportedAudioCodecs { get; set; } + public StreamState(ILiveTvManager liveTvManager, ILogger logger) { _liveTvManager = liveTvManager; _logger = logger; + SupportedAudioCodecs = new List(); } public string InputAudioSync { get; set; } diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index ac6b9290e..e15c32518 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -15,6 +15,44 @@ namespace MediaBrowser.Common.Implementations.Networking /// /// IPAddress. public IEnumerable GetLocalIpAddresses() + { + var list = GetIPsDefault().Where(i => !IPAddress.IsLoopback(i)).Select(i => i.ToString()).ToList(); + + if (list.Count > 0) + { + return list; + } + + return GetLocalIpAddressesFallback(); + } + + private IEnumerable GetIPsDefault() + { + foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) + { + var props = adapter.GetIPProperties(); + var gateways = from ga in props.GatewayAddresses + where !ga.Address.Equals(IPAddress.Any) + select true; + + if (!gateways.Any()) + { + continue; + } + + foreach (var uni in props.UnicastAddresses) + { + var address = uni.Address; + if (address.AddressFamily != AddressFamily.InterNetwork) + { + continue; + } + yield return address; + } + } + } + + private IEnumerable GetLocalIpAddressesFallback() { var host = Dns.GetHostEntry(Dns.GetHostName()); @@ -25,7 +63,7 @@ namespace MediaBrowser.Common.Implementations.Networking .Select(i => i.ToString()) .Reverse(); } - + /// /// Gets a random port number that is currently available /// @@ -50,6 +88,7 @@ namespace MediaBrowser.Common.Implementations.Networking .Select(i => BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes())) .FirstOrDefault(); } + /// /// Parses the specified endpointstring. /// diff --git a/MediaBrowser.Controller/Dlna/ControlRequest.cs b/MediaBrowser.Controller/Dlna/ControlRequest.cs new file mode 100644 index 000000000..74e68b7d0 --- /dev/null +++ b/MediaBrowser.Controller/Dlna/ControlRequest.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Dlna +{ + public class ControlRequest + { + public IDictionary Headers { get; set; } + + public string InputXml { get; set; } + + public ControlRequest() + { + Headers = new Dictionary(); + } + } + + public class ControlResponse + { + public IDictionary Headers { get; set; } + + public string Xml { get; set; } + + public ControlResponse() + { + Headers = new Dictionary(); + } + } +} diff --git a/MediaBrowser.Controller/Dlna/IDlnaManager.cs b/MediaBrowser.Controller/Dlna/IDlnaManager.cs index 521d17e01..bcccaaa2e 100644 --- a/MediaBrowser.Controller/Dlna/IDlnaManager.cs +++ b/MediaBrowser.Controller/Dlna/IDlnaManager.cs @@ -55,5 +55,27 @@ namespace MediaBrowser.Controller.Dlna /// The device information. /// DeviceProfile. DeviceProfile GetProfile(DeviceIdentification deviceInfo); + + /// + /// Gets the server description XML. + /// + /// The headers. + /// The server uu identifier. + /// System.String. + string GetServerDescriptionXml(IDictionary headers, string serverUuId); + + /// + /// Gets the content directory XML. + /// + /// The headers. + /// System.String. + string GetContentDirectoryXml(IDictionary headers); + + /// + /// Processes the control request. + /// + /// The request. + /// ControlResponse. + ControlResponse ProcessControlRequest(ControlRequest request); } } diff --git a/MediaBrowser.Controller/LiveTv/LiveStreamInfo.cs b/MediaBrowser.Controller/LiveTv/LiveStreamInfo.cs index 8e1f94178..019c9d31a 100644 --- a/MediaBrowser.Controller/LiveTv/LiveStreamInfo.cs +++ b/MediaBrowser.Controller/LiveTv/LiveStreamInfo.cs @@ -1,4 +1,6 @@ - +using MediaBrowser.Model.Entities; +using System.Collections.Generic; + namespace MediaBrowser.Controller.LiveTv { public class LiveStreamInfo @@ -20,5 +22,22 @@ namespace MediaBrowser.Controller.LiveTv /// /// The identifier. public string Id { get; set; } + + /// + /// Gets or sets the media container. + /// + /// The media container. + public string MediaContainer { get; set; } + + /// + /// Gets or sets the media streams. + /// + /// The media streams. + public List MediaStreams { get; set; } + + public LiveStreamInfo() + { + MediaStreams = new List(); + } } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 3082d12ca..692a7a92e 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -78,6 +78,7 @@ + diff --git a/MediaBrowser.Dlna/Common/Argument.cs b/MediaBrowser.Dlna/Common/Argument.cs new file mode 100644 index 000000000..a3ff8ecc8 --- /dev/null +++ b/MediaBrowser.Dlna/Common/Argument.cs @@ -0,0 +1,12 @@ + +namespace MediaBrowser.Dlna.Common +{ + public class Argument + { + public string Name { get; set; } + + public string Direction { get; set; } + + public string RelatedStateVariable { get; set; } + } +} diff --git a/MediaBrowser.Dlna/Common/DeviceIcon.cs b/MediaBrowser.Dlna/Common/DeviceIcon.cs new file mode 100644 index 000000000..bec10dcc5 --- /dev/null +++ b/MediaBrowser.Dlna/Common/DeviceIcon.cs @@ -0,0 +1,21 @@ + +namespace MediaBrowser.Dlna.Common +{ + public class DeviceIcon + { + public string Url { get; set; } + + public string MimeType { get; set; } + + public int Width { get; set; } + + public int Height { get; set; } + + public string Depth { get; set; } + + public override string ToString() + { + return string.Format("{0}x{1}", Height, Width); + } + } +} diff --git a/MediaBrowser.Dlna/Common/DeviceService.cs b/MediaBrowser.Dlna/Common/DeviceService.cs new file mode 100644 index 000000000..8f8b175a4 --- /dev/null +++ b/MediaBrowser.Dlna/Common/DeviceService.cs @@ -0,0 +1,21 @@ + +namespace MediaBrowser.Dlna.Common +{ + public class DeviceService + { + public string ServiceType { get; set; } + + public string ServiceId { get; set; } + + public string ScpdUrl { get; set; } + + public string ControlUrl { get; set; } + + public string EventSubUrl { get; set; } + + public override string ToString() + { + return string.Format("{0}", ServiceId); + } + } +} diff --git a/MediaBrowser.Dlna/Common/ServiceAction.cs b/MediaBrowser.Dlna/Common/ServiceAction.cs new file mode 100644 index 000000000..7685e217e --- /dev/null +++ b/MediaBrowser.Dlna/Common/ServiceAction.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Dlna.Common +{ + public class ServiceAction + { + public string Name { get; set; } + + public List ArgumentList { get; set; } + + public override string ToString() + { + return Name; + } + + public ServiceAction() + { + ArgumentList = new List(); + } + } +} diff --git a/MediaBrowser.Dlna/Common/StateVariable.cs b/MediaBrowser.Dlna/Common/StateVariable.cs new file mode 100644 index 000000000..21771e7b8 --- /dev/null +++ b/MediaBrowser.Dlna/Common/StateVariable.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Dlna.Common +{ + public class StateVariable + { + public string Name { get; set; } + + public string DataType { get; set; } + + public bool SendsEvents { get; set; } + + public List AllowedValues { get; set; } + + public override string ToString() + { + return Name; + } + + public StateVariable() + { + AllowedValues = new List(); + } + } +} diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 7a8fd4183..624f23f7f 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -1,9 +1,9 @@ -using System.Text; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Dlna; using MediaBrowser.Dlna.Profiles; +using MediaBrowser.Dlna.Server; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Text.RegularExpressions; namespace MediaBrowser.Dlna @@ -476,5 +477,26 @@ namespace MediaBrowser.Dlna internal DeviceProfileInfo Info { get; set; } internal string Path { get; set; } } + + public string GetServerDescriptionXml(IDictionary headers, string serverUuId) + { + var profile = GetProfile(headers) ?? + GetDefaultProfile(); + + return new DescriptionXmlBuilder(profile, serverUuId).GetXml(); + } + + public string GetContentDirectoryXml(IDictionary headers) + { + var profile = GetProfile(headers) ?? + GetDefaultProfile(); + + return new ContentDirectoryXmlBuilder(profile).GetXml(); + } + + public ControlResponse ProcessControlRequest(ControlRequest request) + { + return new ControlHandler(_logger).ProcessControlRequest(request); + } } } \ No newline at end of file diff --git a/MediaBrowser.Dlna/Images/logo-120.jpg b/MediaBrowser.Dlna/Images/logo-120.jpg new file mode 100644 index 000000000..1de803c8f Binary files /dev/null and b/MediaBrowser.Dlna/Images/logo-120.jpg differ diff --git a/MediaBrowser.Dlna/Images/logo-120.png b/MediaBrowser.Dlna/Images/logo-120.png new file mode 100644 index 000000000..2dd04d468 Binary files /dev/null and b/MediaBrowser.Dlna/Images/logo-120.png differ diff --git a/MediaBrowser.Dlna/Images/logo-48.jpg b/MediaBrowser.Dlna/Images/logo-48.jpg new file mode 100644 index 000000000..f1e7302aa Binary files /dev/null and b/MediaBrowser.Dlna/Images/logo-48.jpg differ diff --git a/MediaBrowser.Dlna/Images/logo-48.png b/MediaBrowser.Dlna/Images/logo-48.png new file mode 100644 index 000000000..3b13d141c Binary files /dev/null and b/MediaBrowser.Dlna/Images/logo-48.png differ diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index d1fed4572..0980ee81d 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -52,13 +52,13 @@ Properties\SharedVersion.cs - + Code - + @@ -68,20 +68,25 @@ - + + + + + + - + - + @@ -141,6 +146,12 @@ + + + + + +