diff options
Diffstat (limited to 'MediaBrowser.Api/Subtitles/SubtitleService.cs')
| -rw-r--r-- | MediaBrowser.Api/Subtitles/SubtitleService.cs | 82 |
1 files changed, 78 insertions, 4 deletions
diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index 3e692cb22..dc5799239 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -1,6 +1,4 @@ -using System.IO; -using System.Linq; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Net; @@ -11,6 +9,10 @@ using MediaBrowser.Model.Providers; using ServiceStack; using System; using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -69,7 +71,8 @@ namespace MediaBrowser.Api.Subtitles public string Id { get; set; } } - [Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/Stream.{Format}", "GET", Summary = "Gets subtitles in a specified format (vtt).")] + [Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/Stream.{Format}", "GET", Summary = "Gets subtitles in a specified format.")] + [Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/{StartPositionTicks}/Stream.{Format}", "GET", Summary = "Gets subtitles in a specified format.")] public class GetSubtitle { /// <summary> @@ -90,6 +93,29 @@ namespace MediaBrowser.Api.Subtitles [ApiMember(Name = "StartPositionTicks", Description = "StartPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public long StartPositionTicks { get; set; } + + [ApiMember(Name = "EndPositionTicks", Description = "EndPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public long? EndPositionTicks { get; set; } + } + + [Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/subtitles.m3u8", "GET", Summary = "Gets an HLS subtitle playlist.")] + public class GetSubtitlePlaylist + { + /// <summary> + /// Gets or sets the id. + /// </summary> + /// <value>The id.</value> + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + + [ApiMember(Name = "MediaSourceId", Description = "MediaSourceId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string MediaSourceId { get; set; } + + [ApiMember(Name = "Index", Description = "The subtitle stream index", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")] + public int Index { get; set; } + + [ApiMember(Name = "SegmentLength", Description = "The subtitle srgment length", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")] + public int SegmentLength { get; set; } } public class SubtitleService : BaseApiService @@ -105,6 +131,53 @@ namespace MediaBrowser.Api.Subtitles _subtitleEncoder = subtitleEncoder; } + public object Get(GetSubtitlePlaylist request) + { + var item = (Video)_libraryManager.GetItemById(new Guid(request.Id)); + + var mediaSource = item.GetMediaSources(false) + .First(i => string.Equals(i.Id, request.MediaSourceId ?? request.Id)); + + var builder = new StringBuilder(); + + var runtime = mediaSource.RunTimeTicks ?? -1; + + if (runtime <= 0) + { + throw new ArgumentException("HLS Subtitles are not supported for this media."); + } + + builder.AppendLine("#EXTM3U"); + builder.AppendLine("#EXT-X-TARGETDURATION:" + request.SegmentLength.ToString(CultureInfo.InvariantCulture)); + builder.AppendLine("#EXT-X-VERSION:3"); + builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0"); + + long positionTicks = 0; + var segmentLengthTicks = TimeSpan.FromSeconds(request.SegmentLength).Ticks; + + while (positionTicks < runtime) + { + var remaining = runtime - positionTicks; + var lengthTicks = Math.Min(remaining, segmentLengthTicks); + + builder.AppendLine("#EXTINF:" + TimeSpan.FromTicks(lengthTicks).TotalSeconds.ToString(CultureInfo.InvariantCulture)); + + var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks); + + var url = string.Format("stream.srt?StartPositionTicks={0}&EndPositionTicks={1}", + positionTicks.ToString(CultureInfo.InvariantCulture), + endPositionTicks.ToString(CultureInfo.InvariantCulture)); + + builder.AppendLine(url); + + positionTicks += segmentLengthTicks; + } + + builder.AppendLine("#EXT-X-ENDLIST"); + + return ResultFactory.GetResult(builder.ToString(), Common.Net.MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>()); + } + public object Get(GetSubtitle request) { if (string.IsNullOrEmpty(request.Format)) @@ -132,6 +205,7 @@ namespace MediaBrowser.Api.Subtitles request.Index, request.Format, request.StartPositionTicks, + request.EndPositionTicks, CancellationToken.None).ConfigureAwait(false); } |
