From 9b8c0d68ce3e816c86a66702a7f5036760a42413 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 9 Jul 2014 10:39:04 -0400 Subject: update mono build --- MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj | 3 +++ 1 file changed, 3 insertions(+) (limited to 'MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj') diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index d2c21639c..f11c261e2 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -52,6 +52,9 @@ + + Properties\SharedVersion.cs + -- cgit v1.2.3 From a118169a3ccf3361a5920794c7762dfcff1babd2 Mon Sep 17 00:00:00 2001 From: gsnerf Date: Wed, 6 Aug 2014 01:06:45 +0200 Subject: removed block of NuGet.targets for 'Release Mono' --- .../MediaBrowser.Common.Implementations.csproj | 3 ++- MediaBrowser.Controller/MediaBrowser.Controller.csproj | 3 ++- MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj | 5 +++-- MediaBrowser.Providers/MediaBrowser.Providers.csproj | 5 +++-- .../MediaBrowser.Server.Implementations.csproj | 3 ++- MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 ++- 6 files changed, 14 insertions(+), 8 deletions(-) (limited to 'MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj') diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index fe6da7e4f..954d9bfe3 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -122,7 +122,8 @@ - + + if '$(ConfigurationName)' == 'Release' ( xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 3ecf5ef45..610510109 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -349,7 +349,8 @@ xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i - + + + - \ No newline at end of file + diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 9a26101a1..7657e6ca8 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -205,7 +205,8 @@ - + + - \ No newline at end of file + diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 9dd16e7c3..f5837c4ca 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -481,7 +481,8 @@ - + + + if '$(ConfigurationName)' == 'Release' ( diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index fd41c7e9e..661073c89 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -116,7 +116,7 @@ - + if '$(ConfigurationName)' == 'Release' ( xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 6a9c4edbb..5243e1a2a 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -352,7 +352,6 @@ xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i - - \ No newline at end of file + diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index fb0421678..76a1e52f5 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -205,7 +205,6 @@ - - + \ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs new file mode 100644 index 000000000..e5a727428 --- /dev/null +++ b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading; + +namespace MediaBrowser.MediaEncoding.Subtitles +{ + public class AssParser : ISubtitleParser + { + private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + + public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken) + { + var trackInfo = new SubtitleTrackInfo(); + var eventIndex = 1; + using (var reader = new StreamReader(stream)) + { + string line; + while (reader.ReadLine() != "[Events]") + {} + var headers = ParseFieldHeaders(reader.ReadLine()); + + while ((line = reader.ReadLine()) != null) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + if(line.StartsWith("[")) + break; + if(string.IsNullOrEmpty(line)) + continue; + var subEvent = new SubtitleTrackEvent { Id = eventIndex.ToString(_usCulture) }; + eventIndex++; + var sections = line.Substring(10).Split(','); + + subEvent.StartPositionTicks = GetTicks(sections[headers["Start"]]); + subEvent.EndPositionTicks = GetTicks(sections[headers["End"]]); + subEvent.Text = string.Join(",", sections.Skip(headers["Text"])); + subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase); + + trackInfo.TrackEvents.Add(subEvent); + } + } + return trackInfo; + } + + long GetTicks(string time) + { + TimeSpan span; + return TimeSpan.TryParseExact(time, @"h\:mm\:ss\.ff", _usCulture, out span) + ? span.Ticks: 0; + } + + private Dictionary ParseFieldHeaders(string line) { + var fields = line.Substring(8).Split(',').Select(x=>x.Trim()).ToList(); + + var result = new Dictionary { + {"Start", fields.IndexOf("Start")}, + {"End", fields.IndexOf("End")}, + {"Text", fields.IndexOf("Text")} + }; + return result; + } + } +} diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs index e21804f6c..4b11d55ce 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs @@ -1,71 +1,391 @@ using System; -using System.Collections.Generic; -using System.Globalization; using System.IO; -using System.Linq; -using System.Text.RegularExpressions; +using System.Text; using System.Threading; namespace MediaBrowser.MediaEncoding.Subtitles { + /// + /// Credit to https://github.com/SubtitleEdit/subtitleedit/blob/a299dc4407a31796364cc6ad83f0d3786194ba22/src/Logic/SubtitleFormats/SubStationAlpha.cs + /// public class SsaParser : ISubtitleParser { - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken) { var trackInfo = new SubtitleTrackInfo(); - var eventIndex = 1; + using (var reader = new StreamReader(stream)) { + bool eventsStarted = false; + + string[] format = "Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text".Split(','); + int indexLayer = 0; + int indexStart = 1; + int indexEnd = 2; + int indexStyle = 3; + int indexName = 4; + int indexEffect = 8; + int indexText = 9; + int lineNumber = 0; + + var header = new StringBuilder(); + string line; - while (reader.ReadLine() != "[Events]") - {} - var headers = ParseFieldHeaders(reader.ReadLine()); while ((line = reader.ReadLine()) != null) { cancellationToken.ThrowIfCancellationRequested(); - - if (string.IsNullOrWhiteSpace(line)) + + lineNumber++; + if (!eventsStarted) + header.AppendLine(line); + + if (line.Trim().ToLower() == "[events]") { - continue; + eventsStarted = true; } - if(line.StartsWith("[")) - break; - if(string.IsNullOrEmpty(line)) - continue; - var subEvent = new SubtitleTrackEvent { Id = eventIndex.ToString(_usCulture) }; - eventIndex++; - var sections = line.Substring(10).Split(','); - - subEvent.StartPositionTicks = GetTicks(sections[headers["Start"]]); - subEvent.EndPositionTicks = GetTicks(sections[headers["End"]]); - subEvent.Text = string.Join(",", sections.Skip(headers["Text"])); - subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase); - - trackInfo.TrackEvents.Add(subEvent); - } + else if (!string.IsNullOrEmpty(line) && line.Trim().StartsWith(";")) + { + // skip comment lines + } + else if (eventsStarted && line.Trim().Length > 0) + { + string s = line.Trim().ToLower(); + if (s.StartsWith("format:")) + { + if (line.Length > 10) + { + format = line.ToLower().Substring(8).Split(','); + for (int i = 0; i < format.Length; i++) + { + if (format[i].Trim().ToLower() == "layer") + indexLayer = i; + else if (format[i].Trim().ToLower() == "start") + indexStart = i; + else if (format[i].Trim().ToLower() == "end") + indexEnd = i; + else if (format[i].Trim().ToLower() == "text") + indexText = i; + else if (format[i].Trim().ToLower() == "effect") + indexEffect = i; + else if (format[i].Trim().ToLower() == "style") + indexStyle = i; + } + } + } + else if (!string.IsNullOrEmpty(s)) + { + string text = string.Empty; + string start = string.Empty; + string end = string.Empty; + string style = string.Empty; + string layer = string.Empty; + string effect = string.Empty; + string name = string.Empty; + + string[] splittedLine; + + if (s.StartsWith("dialogue:")) + splittedLine = line.Substring(10).Split(','); + else + splittedLine = line.Split(','); + + for (int i = 0; i < splittedLine.Length; i++) + { + if (i == indexStart) + start = splittedLine[i].Trim(); + else if (i == indexEnd) + end = splittedLine[i].Trim(); + else if (i == indexLayer) + layer = splittedLine[i]; + else if (i == indexEffect) + effect = splittedLine[i]; + else if (i == indexText) + text = splittedLine[i]; + else if (i == indexStyle) + style = splittedLine[i]; + else if (i == indexName) + name = splittedLine[i]; + else if (i > indexText) + text += "," + splittedLine[i]; + } + + try + { + var p = new SubtitleTrackEvent(); + + p.StartPositionTicks = GetTimeCodeFromString(start); + p.EndPositionTicks = GetTimeCodeFromString(end); + p.Text = GetFormattedText(text); + + trackInfo.TrackEvents.Add(p); + } + catch + { + } + } + } + } + + //if (header.Length > 0) + //subtitle.Header = header.ToString(); + + //subtitle.Renumber(1); } return trackInfo; } - long GetTicks(string time) + private static long GetTimeCodeFromString(string time) + { + // h:mm:ss.cc + string[] timeCode = time.Split(':', '.'); + return new TimeSpan(0, int.Parse(timeCode[0]), + int.Parse(timeCode[1]), + int.Parse(timeCode[2]), + int.Parse(timeCode[3]) * 10).Ticks; + } + + public static string GetFormattedText(string text) + { + text = text.Replace("\\N", Environment.NewLine).Replace("\\n", Environment.NewLine); + bool italic = false; + + for (int i = 0; i < 10; i++) // just look ten times... + { + if (text.Contains(@"{\fn")) + { + int start = text.IndexOf(@"{\fn"); + int end = text.IndexOf('}', start); + if (end > 0 && !text.Substring(start).StartsWith("{\\fn}")) + { + string fontName = text.Substring(start + 4, end - (start + 4)); + string extraTags = string.Empty; + CheckAndAddSubTags(ref fontName, ref extraTags, out italic); + text = text.Remove(start, end - start + 1); + if (italic) + text = text.Insert(start, ""); + else + text = text.Insert(start, ""); + + int indexOfEndTag = text.IndexOf("{\\fn}", start); + if (indexOfEndTag > 0) + text = text.Remove(indexOfEndTag, "{\\fn}".Length).Insert(indexOfEndTag, ""); + else + text += ""; + } + } + + if (text.Contains(@"{\fs")) + { + int start = text.IndexOf(@"{\fs"); + int end = text.IndexOf('}', start); + if (end > 0 && !text.Substring(start).StartsWith("{\\fs}")) + { + string fontSize = text.Substring(start + 4, end - (start + 4)); + string extraTags = string.Empty; + CheckAndAddSubTags(ref fontSize, ref extraTags, out italic); + if (IsInteger(fontSize)) + { + text = text.Remove(start, end - start + 1); + if (italic) + text = text.Insert(start, ""); + else + text = text.Insert(start, ""); + + int indexOfEndTag = text.IndexOf("{\\fs}", start); + if (indexOfEndTag > 0) + text = text.Remove(indexOfEndTag, "{\\fs}".Length).Insert(indexOfEndTag, ""); + else + text += ""; + } + } + } + + if (text.Contains(@"{\c")) + { + int start = text.IndexOf(@"{\c"); + int end = text.IndexOf('}', start); + if (end > 0 && !text.Substring(start).StartsWith("{\\c}")) + { + string color = text.Substring(start + 4, end - (start + 4)); + string extraTags = string.Empty; + CheckAndAddSubTags(ref color, ref extraTags, out italic); + + color = color.Replace("&", string.Empty).TrimStart('H'); + color = color.PadLeft(6, '0'); + + // switch to rrggbb from bbggrr + color = "#" + color.Remove(color.Length - 6) + color.Substring(color.Length - 2, 2) + color.Substring(color.Length - 4, 2) + color.Substring(color.Length - 6, 2); + color = color.ToLower(); + + text = text.Remove(start, end - start + 1); + if (italic) + text = text.Insert(start, ""); + else + text = text.Insert(start, ""); + int indexOfEndTag = text.IndexOf("{\\c}", start); + if (indexOfEndTag > 0) + text = text.Remove(indexOfEndTag, "{\\c}".Length).Insert(indexOfEndTag, ""); + else + text += ""; + } + } + + if (text.Contains(@"{\1c")) // "1" specifices primary color + { + int start = text.IndexOf(@"{\1c"); + int end = text.IndexOf('}', start); + if (end > 0 && !text.Substring(start).StartsWith("{\\1c}")) + { + string color = text.Substring(start + 5, end - (start + 5)); + string extraTags = string.Empty; + CheckAndAddSubTags(ref color, ref extraTags, out italic); + + color = color.Replace("&", string.Empty).TrimStart('H'); + color = color.PadLeft(6, '0'); + + // switch to rrggbb from bbggrr + color = "#" + color.Remove(color.Length - 6) + color.Substring(color.Length - 2, 2) + color.Substring(color.Length - 4, 2) + color.Substring(color.Length - 6, 2); + color = color.ToLower(); + + text = text.Remove(start, end - start + 1); + if (italic) + text = text.Insert(start, ""); + else + text = text.Insert(start, ""); + text += ""; + } + } + + } + + text = text.Replace(@"{\i1}", ""); + text = text.Replace(@"{\i0}", ""); + text = text.Replace(@"{\i}", ""); + if (CountTagInText(text, "") > CountTagInText(text, "")) + text += ""; + + text = text.Replace(@"{\u1}", ""); + text = text.Replace(@"{\u0}", ""); + text = text.Replace(@"{\u}", ""); + if (CountTagInText(text, "") > CountTagInText(text, "")) + text += ""; + + text = text.Replace(@"{\b1}", ""); + text = text.Replace(@"{\b0}", ""); + text = text.Replace(@"{\b}", ""); + if (CountTagInText(text, "") > CountTagInText(text, "")) + text += ""; + + return text; + } + + private static bool IsInteger(string s) { - TimeSpan span; - return TimeSpan.TryParseExact(time, @"h\:mm\:ss\.ff", _usCulture, out span) - ? span.Ticks: 0; + int i; + if (int.TryParse(s, out i)) + return true; + return false; } - private Dictionary ParseFieldHeaders(string line) { - var fields = line.Substring(8).Split(',').Select(x=>x.Trim()).ToList(); + private static int CountTagInText(string text, string tag) + { + int count = 0; + int index = text.IndexOf(tag); + while (index >= 0) + { + count++; + if (index == text.Length) + return count; + index = text.IndexOf(tag, index + 1); + } + return count; + } + + private static void CheckAndAddSubTags(ref string tagName, ref string extraTags, out bool italic) + { + italic = false; + int indexOfSPlit = tagName.IndexOf(@"\"); + if (indexOfSPlit > 0) + { + string rest = tagName.Substring(indexOfSPlit).TrimStart('\\'); + tagName = tagName.Remove(indexOfSPlit); + + for (int i = 0; i < 10; i++) + { + if (rest.StartsWith("fs") && rest.Length > 2) + { + indexOfSPlit = rest.IndexOf(@"\"); + string fontSize = rest; + if (indexOfSPlit > 0) + { + fontSize = rest.Substring(0, indexOfSPlit); + rest = rest.Substring(indexOfSPlit).TrimStart('\\'); + } + else + { + rest = string.Empty; + } + extraTags += " size=\"" + fontSize.Substring(2) + "\""; + } + else if (rest.StartsWith("fn") && rest.Length > 2) + { + indexOfSPlit = rest.IndexOf(@"\"); + string fontName = rest; + if (indexOfSPlit > 0) + { + fontName = rest.Substring(0, indexOfSPlit); + rest = rest.Substring(indexOfSPlit).TrimStart('\\'); + } + else + { + rest = string.Empty; + } + extraTags += " face=\"" + fontName.Substring(2) + "\""; + } + else if (rest.StartsWith("c") && rest.Length > 2) + { + indexOfSPlit = rest.IndexOf(@"\"); + string fontColor = rest; + if (indexOfSPlit > 0) + { + fontColor = rest.Substring(0, indexOfSPlit); + rest = rest.Substring(indexOfSPlit).TrimStart('\\'); + } + else + { + rest = string.Empty; + } + + string color = fontColor.Substring(2); + color = color.Replace("&", string.Empty).TrimStart('H'); + color = color.PadLeft(6, '0'); + // switch to rrggbb from bbggrr + color = "#" + color.Remove(color.Length - 6) + color.Substring(color.Length - 2, 2) + color.Substring(color.Length - 4, 2) + color.Substring(color.Length - 6, 2); + color = color.ToLower(); - var result = new Dictionary { - {"Start", fields.IndexOf("Start")}, - {"End", fields.IndexOf("End")}, - {"Text", fields.IndexOf("Text")} - }; - return result; + extraTags += " color=\"" + color + "\""; + } + else if (rest.StartsWith("i1") && rest.Length > 1) + { + indexOfSPlit = rest.IndexOf(@"\"); + italic = true; + if (indexOfSPlit > 0) + { + rest = rest.Substring(indexOfSPlit).TrimStart('\\'); + } + else + { + rest = string.Empty; + } + } + else if (rest.Length > 0 && rest.Contains("\\")) + { + indexOfSPlit = rest.IndexOf(@"\"); + rest = rest.Substring(indexOfSPlit).TrimStart('\\'); + } + } + } } } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 82e331dd8..c083cad4e 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -239,11 +239,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles { return new SrtParser(); } - if (string.Equals(format, SubtitleFormat.SSA, StringComparison.OrdinalIgnoreCase) || - string.Equals(format, SubtitleFormat.ASS, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(format, SubtitleFormat.SSA, StringComparison.OrdinalIgnoreCase)) { return new SsaParser(); } + if (string.Equals(format, SubtitleFormat.ASS, StringComparison.OrdinalIgnoreCase)) + { + return new AssParser(); + } if (throwIfMissing) { diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index af37a2be0..4ccafd590 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -1271,8 +1271,9 @@ namespace MediaBrowser.Model.ApiClient /// /// The playlist identifier. /// The item ids. + /// The user identifier. /// Task. - Task AddToPlaylist(string playlistId, IEnumerable itemIds); + Task AddToPlaylist(string playlistId, IEnumerable itemIds, string userId); /// /// Removes from playlist. diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index d3e61792f..0dfd27a72 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -1,12 +1,12 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Library; +using MediaBrowser.Model.Providers; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Runtime.Serialization; -using MediaBrowser.Model.Providers; namespace MediaBrowser.Model.Dto { @@ -227,6 +227,12 @@ namespace MediaBrowser.Model.Dto /// The production year. public int? ProductionYear { get; set; } + /// + /// Gets or sets the recursive unplayed item count. + /// + /// The recursive unplayed item count. + public int? RecursiveUnplayedItemCount { get; set; } + /// /// Gets or sets the season count. /// diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 2010b495c..2c683991c 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1366,6 +1366,7 @@ namespace MediaBrowser.Server.Implementations.Dto dto.RecursiveItemCount = recursiveItemCount; dto.UserData.UnplayedItemCount = unplayed; + dto.RecursiveUnplayedItemCount = unplayed; if (recursiveItemCount > 0) { diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs index 07c937389..ee2114aa4 100644 --- a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs +++ b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs @@ -82,7 +82,7 @@ namespace MediaBrowser.Server.Implementations.Playlists if (folder != null) { options.MediaType = folder.GetRecursiveChildren() - .Where(i => !i.IsFolder) + .Where(i => !i.IsFolder && i.SupportsAddingToPlaylist) .Select(i => i.MediaType) .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); } @@ -100,6 +100,8 @@ namespace MediaBrowser.Server.Implementations.Playlists throw new ArgumentException("A playlist media type is required."); } + var user = _userManager.GetUserById(new Guid(options.UserId)); + var path = Path.Combine(parentFolder.Path, folderName); path = GetTargetPath(path); @@ -126,7 +128,7 @@ namespace MediaBrowser.Server.Implementations.Playlists if (options.ItemIdList.Count > 0) { - await AddToPlaylist(playlist.Id.ToString("N"), options.ItemIdList); + await AddToPlaylistInternal(playlist.Id.ToString("N"), options.ItemIdList, user); } return new PlaylistCreationResult @@ -151,14 +153,21 @@ namespace MediaBrowser.Server.Implementations.Playlists return path; } - private IEnumerable GetPlaylistItems(IEnumerable itemIds, string playlistMediaType) + private IEnumerable GetPlaylistItems(IEnumerable itemIds, string playlistMediaType, User user) { var items = itemIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null); - return Playlist.GetPlaylistItems(playlistMediaType, items, null); + return Playlist.GetPlaylistItems(playlistMediaType, items, user); } - public async Task AddToPlaylist(string playlistId, IEnumerable itemIds) + public Task AddToPlaylist(string playlistId, IEnumerable itemIds, string userId) + { + var user = string.IsNullOrWhiteSpace(userId) ? null : _userManager.GetUserById(new Guid(userId)); + + return AddToPlaylistInternal(playlistId, itemIds, user); + } + + private async Task AddToPlaylistInternal(string playlistId, IEnumerable itemIds, User user) { var playlist = _libraryManager.GetItemById(playlistId) as Playlist; @@ -170,7 +179,9 @@ namespace MediaBrowser.Server.Implementations.Playlists var list = new List(); var itemList = new List(); - var items = GetPlaylistItems(itemIds, playlist.MediaType).ToList(); + var items = GetPlaylistItems(itemIds, playlist.MediaType, user) + .Where(i => i.SupportsAddingToPlaylist) + .ToList(); foreach (var item in items) { @@ -183,7 +194,6 @@ namespace MediaBrowser.Server.Implementations.Playlists await playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); await playlist.RefreshMetadata(new MetadataRefreshOptions { - ForceSave = true }, CancellationToken.None).ConfigureAwait(false); diff --git a/MediaBrowser.Tests/MediaEncoding/Subtitles/SsaParserTests.cs b/MediaBrowser.Tests/MediaEncoding/Subtitles/SsaParserTests.cs index 3c278ae41..d869146fd 100644 --- a/MediaBrowser.Tests/MediaEncoding/Subtitles/SsaParserTests.cs +++ b/MediaBrowser.Tests/MediaEncoding/Subtitles/SsaParserTests.cs @@ -39,7 +39,7 @@ namespace MediaBrowser.Tests.MediaEncoding.Subtitles { } }; - var sut = new SsaParser(); + var sut = new AssParser(); var stream = File.OpenRead(@"MediaEncoding\Subtitles\TestSubtitles\data.ssa"); -- cgit v1.2.3 From 21d88faa187f89854f2ab5f5146baea70b6bc118 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 22 Aug 2014 11:47:44 -0400 Subject: added json subtitle output --- MediaBrowser.Api/Subtitles/SubtitleService.cs | 6 ++++- MediaBrowser.Common/Net/MimeTypes.cs | 4 ++++ .../MediaBrowser.MediaEncoding.csproj | 1 + MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs | 27 ++++++++++++++++++++++ .../Subtitles/SubtitleEncoder.cs | 9 +++++++- .../Session/HttpSessionController.cs | 2 +- MediaBrowser.ServerApplication/ApplicationHost.cs | 2 +- 7 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs (limited to 'MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj') diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index dc5799239..6e2882319 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -174,12 +174,16 @@ namespace MediaBrowser.Api.Subtitles } builder.AppendLine("#EXT-X-ENDLIST"); - + return ResultFactory.GetResult(builder.ToString(), Common.Net.MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary()); } public object Get(GetSubtitle request) { + if (string.Equals(request.Format, "js", StringComparison.OrdinalIgnoreCase)) + { + request.Format = "json"; + } if (string.IsNullOrEmpty(request.Format)) { var item = (Video)_libraryManager.GetItemById(new Guid(request.Id)); diff --git a/MediaBrowser.Common/Net/MimeTypes.cs b/MediaBrowser.Common/Net/MimeTypes.cs index ee3b7dad6..bd9668d80 100644 --- a/MediaBrowser.Common/Net/MimeTypes.cs +++ b/MediaBrowser.Common/Net/MimeTypes.cs @@ -203,6 +203,10 @@ namespace MediaBrowser.Common.Net { return "application/x-javascript"; } + if (ext.Equals(".json", StringComparison.OrdinalIgnoreCase)) + { + return JsonMimeType; + } if (ext.Equals(".map", StringComparison.OrdinalIgnoreCase)) { return "application/x-javascript"; diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index 94e3575a1..9263a3187 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -61,6 +61,7 @@ + diff --git a/MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs new file mode 100644 index 000000000..a4fc5d795 --- /dev/null +++ b/MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs @@ -0,0 +1,27 @@ +using MediaBrowser.Model.Serialization; +using System.IO; +using System.Text; +using System.Threading; + +namespace MediaBrowser.MediaEncoding.Subtitles +{ + public class JsonWriter : ISubtitleWriter + { + private readonly IJsonSerializer _json; + + public JsonWriter(IJsonSerializer json) + { + _json = json; + } + + public void Write(SubtitleTrackInfo info, Stream stream, CancellationToken cancellationToken) + { + using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) + { + var json = _json.SerializeToString(info); + + writer.Write(json); + } + } + } +} diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index c083cad4e..1e839c5a3 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -7,6 +7,7 @@ using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; using System.Diagnostics; @@ -26,14 +27,16 @@ namespace MediaBrowser.MediaEncoding.Subtitles private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; private readonly IMediaEncoder _mediaEncoder; + private readonly IJsonSerializer _json; - public SubtitleEncoder(ILibraryManager libraryManager, ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem, IMediaEncoder mediaEncoder) + public SubtitleEncoder(ILibraryManager libraryManager, ILogger logger, IApplicationPaths appPaths, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IJsonSerializer json) { _libraryManager = libraryManager; _logger = logger; _appPaths = appPaths; _fileSystem = fileSystem; _mediaEncoder = mediaEncoder; + _json = json; } private string SubtitleCachePath @@ -263,6 +266,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles throw new ArgumentNullException("format"); } + if (string.Equals(format, "json", StringComparison.OrdinalIgnoreCase)) + { + return new JsonWriter(_json); + } if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase)) { return new SrtWriter(); diff --git a/MediaBrowser.Server.Implementations/Session/HttpSessionController.cs b/MediaBrowser.Server.Implementations/Session/HttpSessionController.cs index 1be4eca23..a719e8be2 100644 --- a/MediaBrowser.Server.Implementations/Session/HttpSessionController.cs +++ b/MediaBrowser.Server.Implementations/Session/HttpSessionController.cs @@ -54,7 +54,7 @@ namespace MediaBrowser.Server.Implementations.Session { get { - return (DateTime.UtcNow - Session.LastActivityDate).TotalMinutes <= 10; + return (DateTime.UtcNow - Session.LastActivityDate).TotalMinutes <= 20; } } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 35ee580b5..00cefdb22 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -535,7 +535,7 @@ namespace MediaBrowser.ServerApplication RegisterSingleInstance(new SessionContext(UserManager, authContext, SessionManager)); RegisterSingleInstance(new AuthService(UserManager, SessionManager, authContext, ServerConfigurationManager)); - RegisterSingleInstance(new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder)); + RegisterSingleInstance(new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer)); var displayPreferencesTask = Task.Run(async () => await ConfigureDisplayPreferencesRepositories().ConfigureAwait(false)); var itemsTask = Task.Run(async () => await ConfigureItemRepositories().ConfigureAwait(false)); -- cgit v1.2.3