diff options
6 files changed, 101 insertions, 60 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 /// <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, 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) - { - 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 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) + { + + } + /// <summary> /// Converts ffprobe stream info to our MediaStream class /// </summary> @@ -430,16 +476,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)) { @@ -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 /// </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 +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 @@ -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,6 +42,11 @@ 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> 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 @@ <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,6 @@ <Content Include="dashboard-ui\favorites.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <None Include="dashboard-ui\legacy\deferred.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
<Content Include="dashboard-ui\livetvguideprovider.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
|
