diff options
Diffstat (limited to 'MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs')
| -rw-r--r-- | MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 73 |
1 files changed, 64 insertions, 9 deletions
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 10543351b9..53cc41501e 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -5,6 +5,8 @@ using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using ServiceStack; using System; @@ -18,20 +20,20 @@ using System.Threading.Tasks; namespace MediaBrowser.Api.Playback.Hls { - [Route("/Videos/{Id}/master.m3u8", "GET")] - [Api(Description = "Gets a video stream using HTTP live streaming.")] + [Route("/Videos/{Id}/master.m3u8", "GET", Summary = "Gets a video stream using HTTP live streaming.")] public class GetMasterHlsVideoStream : VideoStreamRequest { public bool EnableAdaptiveBitrateStreaming { get; set; } + public SubtitleDeliveryMethod SubtitleMethod { get; set; } + public GetMasterHlsVideoStream() { EnableAdaptiveBitrateStreaming = true; } } - [Route("/Videos/{Id}/main.m3u8", "GET")] - [Api(Description = "Gets a video stream using HTTP live streaming.")] + [Route("/Videos/{Id}/main.m3u8", "GET", Summary = "Gets a video stream using HTTP live streaming.")] public class GetMainHlsVideoStream : VideoStreamRequest { } @@ -359,7 +361,17 @@ namespace MediaBrowser.Api.Playback.Hls var playlistUrl = (state.RunTimeTicks ?? 0) > 0 ? "main.m3u8" : "live.m3u8"; playlistUrl += queryString; - AppendPlaylist(builder, playlistUrl, totalBitrate); + var request = (GetMasterHlsVideoStream) state.Request; + + var subtitleStreams = state.AllMediaStreams + .Where(i => i.IsTextSubtitleStream) + .ToList(); + + var subtitleGroup = subtitleStreams.Count > 0 && request.SubtitleMethod == SubtitleDeliveryMethod.Hls ? + "subs" : + null; + + AppendPlaylist(builder, playlistUrl, totalBitrate, subtitleGroup); if (EnableAdaptiveBitrateStreaming(state)) { @@ -369,16 +381,52 @@ namespace MediaBrowser.Api.Playback.Hls var variation = GetBitrateVariation(totalBitrate); var newBitrate = totalBitrate - variation; - AppendPlaylist(builder, playlistUrl.Replace(requestedVideoBitrate.ToString(UsCulture), (requestedVideoBitrate - variation).ToString(UsCulture)), newBitrate); + AppendPlaylist(builder, playlistUrl.Replace(requestedVideoBitrate.ToString(UsCulture), (requestedVideoBitrate - variation).ToString(UsCulture)), newBitrate, subtitleGroup); variation *= 2; newBitrate = totalBitrate - variation; - AppendPlaylist(builder, playlistUrl.Replace(requestedVideoBitrate.ToString(UsCulture), (requestedVideoBitrate - variation).ToString(UsCulture)), newBitrate); + AppendPlaylist(builder, playlistUrl.Replace(requestedVideoBitrate.ToString(UsCulture), (requestedVideoBitrate - variation).ToString(UsCulture)), newBitrate, subtitleGroup); + } + + if (!string.IsNullOrWhiteSpace(subtitleGroup)) + { + AddSubtitles(state, subtitleStreams, builder); } return builder.ToString(); } + private void AddSubtitles(StreamState state, IEnumerable<MediaStream> subtitles, StringBuilder builder) + { + var selectedIndex = state.SubtitleStream == null ? (int?)null : state.SubtitleStream.Index; + + foreach (var stream in subtitles) + { + const string format = "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"{0}\",DEFAULT={1},FORCED={2},URI=\"{3}\",LANGUAGE=\"{4}\""; + + var name = stream.Language; + + var isDefault = selectedIndex.HasValue && selectedIndex.Value == stream.Index; + var isForced = stream.IsForced; + + if (string.IsNullOrWhiteSpace(name)) name = stream.Codec ?? "Unknown"; + + var url = string.Format("{0}/Subtitles/{1}/subtitles.m3u8?SegmentLength={2}", + state.Request.MediaSourceId, + stream.Index.ToString(UsCulture), + 30.ToString(UsCulture)); + + var line = string.Format(format, + name, + isDefault ? "YES" : "NO", + isForced ? "YES" : "NO", + url, + stream.Language ?? "Unknown"); + + builder.AppendLine(line); + } + } + private bool EnableAdaptiveBitrateStreaming(StreamState state) { var request = state.Request as GetMasterHlsVideoStream; @@ -397,9 +445,16 @@ namespace MediaBrowser.Api.Playback.Hls return state.VideoRequest.VideoBitRate.HasValue; } - private void AppendPlaylist(StringBuilder builder, string url, int bitrate) + private void AppendPlaylist(StringBuilder builder, string url, int bitrate, string subtitleGroup) { - builder.AppendLine("#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" + bitrate.ToString(UsCulture)); + var header = "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" + bitrate.ToString(UsCulture); + + if (!string.IsNullOrWhiteSpace(subtitleGroup)) + { + header += string.Format(",SUBTITLES=\"{0}\"", subtitleGroup); + } + + builder.AppendLine(header); builder.AppendLine(url); } |
