From 1f004c978a902afbd691da20197fb30a3547690f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Feb 2016 22:07:15 -0500 Subject: [PATCH 1/6] add path to ListingsProviderInfo --- MediaBrowser.Model/LiveTv/LiveTvOptions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index 838325d68..095fa95e1 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -47,5 +47,6 @@ namespace MediaBrowser.Model.LiveTv public string ListingsId { get; set; } public string ZipCode { get; set; } public string Country { get; set; } + public string Path { get; set; } } } \ No newline at end of file From ffbe92e51ef8553b91a81f2a57317c51605abea3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 Feb 2016 23:44:31 -0500 Subject: [PATCH 2/6] activate unicast listener --- MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs | 6 +- MediaBrowser.Dlna/Ssdp/SsdpHandler.cs | 154 ++++++++++++++-------- 2 files changed, 100 insertions(+), 60 deletions(-) diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs index 4f7dffdd9..ff936346c 100644 --- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs +++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs @@ -127,10 +127,12 @@ 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; } + + TryCreateDevice(args); } } diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index 881f70165..c2918aed5 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -86,8 +86,25 @@ namespace MediaBrowser.Dlna.Ssdp public event EventHandler MessageReceived; - private async void OnMessageReceived(SsdpMessageEventArgs args) + private async void OnMessageReceived(SsdpMessageEventArgs args, bool isMulticast) { + if (IgnoreMessage(args, isMulticast)) + { + return; + } + + 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); + } + var headers = args.Headers; string st; @@ -108,6 +125,44 @@ namespace MediaBrowser.Dlna.Ssdp EventHelper.FireEventIfNotNull(MessageReceived, this, args, _logger); } + 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 RegisteredDevices { get @@ -126,7 +181,7 @@ namespace MediaBrowser.Dlna.Ssdp RestartSocketListener(); ReloadAliveNotifier(); - //CreateUnicastClient(); + CreateUnicastClient(); SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; @@ -146,6 +201,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 +218,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, @@ -324,20 +380,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 +400,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; @@ -440,6 +463,7 @@ namespace MediaBrowser.Dlna.Ssdp values["NTS"] = "ssdp:" + type; values["NT"] = dev.Type; values["USN"] = dev.USN; + values["X-EMBY-SERVERID"] = _appHost.SystemId; if (logMessage) { @@ -489,14 +513,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 +539,18 @@ namespace MediaBrowser.Dlna.Ssdp /// 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); + } } /// @@ -540,14 +564,21 @@ 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) + { + + } } } @@ -564,13 +595,20 @@ namespace MediaBrowser.Dlna.Ssdp var ipSsdp = IPAddress.Parse(SSDPAddr); var ipTxEnd = new IPEndPoint(ipSsdp, SSDPPort); - for (var i = 0; i < 3; i++) + try { - if (i > 0) + for (var i = 0; i < 3; i++) { - await Task.Delay(50).ConfigureAwait(false); + if (i > 0) + { + await Task.Delay(50).ConfigureAwait(false); + } + _unicastClient.Send(req, req.Length, ipTxEnd); } - _unicastClient.Send(req, req.Length, ipTxEnd); + } + catch (Exception ex) + { + _logger.ErrorException("Error in SendUnicastRequest", ex); } } From f13ca8f343c3e7b782facbaa4e42b7f8a26246b5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Feb 2016 16:24:01 -0500 Subject: [PATCH 3/6] update device discovery --- MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs | 10 ++---- MediaBrowser.Dlna/Ssdp/SsdpHandler.cs | 36 +++++++++++-------- .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 7 +++- ...MediaBrowser.Server.Implementations.csproj | 4 +-- .../packages.config | 2 +- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs index ff936346c..70f6d0e53 100644 --- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs +++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs @@ -132,6 +132,8 @@ namespace MediaBrowser.Dlna.Ssdp return; } + _ssdpHandler.LogMessageReceived(args, true); + TryCreateDevice(args); } } @@ -219,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 c2918aed5..6e85918f4 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -93,17 +93,7 @@ namespace MediaBrowser.Dlna.Ssdp return; } - 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); - } + LogMessageReceived(args, isMulticast); var headers = args.Headers; string st; @@ -125,6 +115,21 @@ 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; @@ -298,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) @@ -473,6 +478,7 @@ namespace MediaBrowser.Dlna.Ssdp var msg = new SsdpMessageBuilder().BuildMessage(header, values); SendDatagram(msg, _ssdpEndp, new IPEndPoint(dev.Address, 0), true); + //SendUnicastRequest(msg, 1); } public void RegisterNotification(string uuid, Uri descriptionUri, IPAddress address, IEnumerable services) @@ -582,7 +588,7 @@ namespace MediaBrowser.Dlna.Ssdp } } - private async void SendUnicastRequest(string request) + private async void SendUnicastRequest(string request, int sendCount = 3) { if (_unicastClient == null) { @@ -597,7 +603,7 @@ namespace MediaBrowser.Dlna.Ssdp try { - for (var i = 0; i < 3; i++) + for (var i = 0; i < sendCount; i++) { if (i > 0) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index 08c42bb46..852b86467 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -42,7 +42,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)) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 5f2fab457..80592c724 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -52,9 +52,9 @@ ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll - + False - ..\packages\MediaBrowser.Naming.1.0.0.47\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + ..\packages\MediaBrowser.Naming.1.0.0.48\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 816f85b42..4f163f8a4 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -3,7 +3,7 @@ - + From bfa1b30cab05577844a9d34e4519c89ebc84aa91 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Feb 2016 16:40:17 -0500 Subject: [PATCH 4/6] update RespondToSearch --- MediaBrowser.Dlna/Ssdp/SsdpHandler.cs | 41 ++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index 6e85918f4..278c34275 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -144,7 +144,7 @@ namespace MediaBrowser.Dlna.Ssdp //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; } } @@ -164,7 +164,7 @@ namespace MediaBrowser.Dlna.Ssdp return true; } } - + return false; } @@ -303,9 +303,17 @@ namespace MediaBrowser.Dlna.Ssdp var msg = new SsdpMessageBuilder().BuildMessage(header, values); - SendDatagram(msg, endpoint, null, false, 2); - SendDatagram(msg, endpoint, new IPEndPoint(d.Address, 0), false, 2); - //SendDatagram(header, values, endpoint, null, true); + var ipEndPoint = endpoint as IPEndPoint; + if (ipEndPoint != null) + { + SendUnicastRequest(msg, ipEndPoint); + } + else + { + SendDatagram(msg, endpoint, null, false, 2); + SendDatagram(msg, endpoint, new IPEndPoint(d.Address, 0), false, 2); + //SendDatagram(header, values, endpoint, null, true); + } if (enableDebugLogging) { @@ -583,12 +591,27 @@ namespace MediaBrowser.Dlna.Ssdp } catch (ObjectDisposedException) { - + } } } - private async void SendUnicastRequest(string request, int sendCount = 3) + private void SendUnicastRequest(string request, int sendCount = 3) + { + if (_unicastClient == null) + { + return; + } + + _logger.Debug("Sending unicast search request"); + + var ipSsdp = IPAddress.Parse(SSDPAddr); + var ipTxEnd = new IPEndPoint(ipSsdp, SSDPPort); + + SendUnicastRequest(request, ipTxEnd, sendCount); + } + + private async void SendUnicastRequest(string request, IPEndPoint toEndPoint, int sendCount = 3) { if (_unicastClient == null) { @@ -598,8 +621,6 @@ namespace MediaBrowser.Dlna.Ssdp _logger.Debug("Sending unicast search request"); byte[] req = Encoding.ASCII.GetBytes(request); - var ipSsdp = IPAddress.Parse(SSDPAddr); - var ipTxEnd = new IPEndPoint(ipSsdp, SSDPPort); try { @@ -609,7 +630,7 @@ namespace MediaBrowser.Dlna.Ssdp { await Task.Delay(50).ConfigureAwait(false); } - _unicastClient.Send(req, req.Length, ipTxEnd); + _unicastClient.Send(req, req.Length, toEndPoint); } } catch (Exception ex) From 76eb1c46e3a2488d954d8981e3f35f5739ec0d4e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Feb 2016 21:55:15 -0500 Subject: [PATCH 5/6] support more embedded video metadata --- .../Encoder/MediaEncoder.cs | 4 +- .../Probing/ProbeResultNormalizer.cs | 129 +++++++++++------- MediaBrowser.Model/MediaInfo/MediaInfo.cs | 10 +- .../MediaInfo/FFProbeAudioInfo.cs | 4 +- .../MediaInfo/FFProbeVideoInfo.cs | 12 ++ .../MediaBrowser.WebDashboard.csproj | 6 +- 6 files changed, 103 insertions(+), 62 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 30e50fecd..ced36f3aa 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -129,7 +129,7 @@ namespace MediaBrowser.MediaEncoding.Encoder /// The request. /// The cancellation token. /// Task. - public Task GetMediaInfo(MediaInfoRequest request, CancellationToken cancellationToken) + public Task GetMediaInfo(MediaInfoRequest request, CancellationToken cancellationToken) { var extractChapters = request.MediaType == DlnaProfileType.Video && request.ExtractChapters; @@ -175,7 +175,7 @@ namespace MediaBrowser.MediaEncoding.Encoder /// The cancellation token. /// Task{MediaInfoResult}. /// ffprobe failed - streams and format are both null. - private async Task GetMediaInfoInternal(string inputPath, + private async Task GetMediaInfoInternal(string inputPath, string primaryPath, MediaProtocol protocol, bool extractChapters, diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 31f6af181..db6278bd4 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -27,7 +27,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 +56,81 @@ namespace MediaBrowser.MediaEncoding.Probing } } - if (isAudio) + var tags = new Dictionary(StringComparer.OrdinalIgnoreCase); + var tagStreamType = isAudio ? "audio" : "video"; + + if (data.streams != null) { - SetAudioRuntimeTicks(data, info); + var tagStream = data.streams.FirstOrDefault(i => string.Equals(i.codec_type, tagStreamType, StringComparison.OrdinalIgnoreCase)); - var tags = new Dictionary(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) + 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 audioStream.tags) - { - tags[pair.Key] = pair.Value; - } - } - } - - if (data.format != null && data.format.tags != null) - { - foreach (var pair in data.format.tags) + foreach (var pair in tagStream.tags) { tags[pair.Key] = pair.Value; } } + } + + if (data.format != null && data.format.tags != null) + { + foreach (var pair in data.format.tags) + { + tags[pair.Key] = pair.Value; + } + } + + FetchGenres(info, tags); + var overview = FFProbeHelpers.GetDictionaryValue(tags, "description"); + if (!string.IsNullOrWhiteSpace(overview)) + { + info.Overview = overview; + } + + 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 audio stream + // so let's create a combined list of both SetAudioInfoFromTags(info, tags); } else { + 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,6 +149,11 @@ namespace MediaBrowser.MediaEncoding.Probing return info; } + private void FetchFromItunesInfo(string xml, MediaInfo info) + { + + } + /// /// Converts ffprobe stream info to our MediaStream class /// @@ -430,16 +476,8 @@ namespace MediaBrowser.MediaEncoding.Probing } } - private void SetAudioInfoFromTags(Model.MediaInfo.MediaInfo audio, Dictionary tags) + private void SetAudioInfoFromTags(MediaInfo audio, Dictionary 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)) { @@ -511,22 +549,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"); @@ -693,7 +721,7 @@ namespace MediaBrowser.MediaEncoding.Probing /// /// The information. /// The tags. - private void FetchGenres(Model.MediaInfo.MediaInfo info, Dictionary tags) + private void FetchGenres(MediaInfo info, Dictionary tags) { var val = FFProbeHelpers.GetDictionaryValue(tags, "genre"); @@ -764,7 +792,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 +803,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.Model/MediaInfo/MediaInfo.cs b/MediaBrowser.Model/MediaInfo/MediaInfo.cs index 21f258693..126710197 100644 --- a/MediaBrowser.Model/MediaInfo/MediaInfo.cs +++ b/MediaBrowser.Model/MediaInfo/MediaInfo.cs @@ -9,11 +9,6 @@ namespace MediaBrowser.Model.MediaInfo { public List Chapters { get; set; } - /// - /// Gets or sets the title. - /// - /// The title. - public string Title { get; set; } /// /// Gets or sets the album. /// @@ -47,6 +42,11 @@ namespace MediaBrowser.Model.MediaInfo /// The official rating. public string OfficialRating { get; set; } /// + /// Gets or sets the official rating description. + /// + /// The official rating description. + public string OfficialRatingDescription { get; set; } + /// /// Gets or sets the overview. /// /// The overview. 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..fb8e25892 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) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 9de20cb39..d4d8be7f1 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -140,6 +140,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -254,9 +257,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From f1745245bac82ad7a6e2b0a647f1ff9092610d9a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Feb 2016 22:18:35 -0500 Subject: [PATCH 6/6] add comment --- MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index db6278bd4..ec51bc967 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -151,7 +151,7 @@ namespace MediaBrowser.MediaEncoding.Probing private void FetchFromItunesInfo(string xml, MediaInfo info) { - + // \n\n\n\n\tcast\n\t\n\t\t\n\t\t\tname\n\t\t\tBlender Foundation\n\t\t\n\t\t\n\t\t\tname\n\t\t\tJanus Bager Kristensen\n\t\t\n\t\n\tdirectors\n\t\n\t\t\n\t\t\tname\n\t\t\tSacha Goedegebure\n\t\t\n\t\n\tstudio\n\tBlender Foundation\n\n\n } ///