aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-08-05 21:09:03 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-08-05 21:09:03 -0400
commit3ff3d04284429d78ec8adc2292de79ef0c022449 (patch)
tree26b5daf7dc3699e4ab9bd41d416195fdbf9f869b
parent3ba6364f259ea43979a88b2a83d64292119057dc (diff)
fixes #888 - Support m3u8 subtitle playlists
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs2
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs73
-rw-r--r--MediaBrowser.Api/Playback/StreamState.cs3
-rw-r--r--MediaBrowser.Api/Subtitles/SubtitleService.cs74
-rw-r--r--MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs5
-rw-r--r--MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs5
-rw-r--r--MediaBrowser.Dlna/Profiles/Windows81Profile.cs5
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Android.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Default.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml7
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml7
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml7
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml2
-rw-r--r--MediaBrowser.Model/Dlna/DeviceProfile.cs6
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs8
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs6
-rw-r--r--MediaBrowser.Model/Dlna/SubtitleProfile.cs3
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs24
33 files changed, 187 insertions, 84 deletions
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 1963ad10a..bfbad5635 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1605,6 +1605,8 @@ namespace MediaBrowser.Api.Playback
{
state.AudioStream = GetMediaStream(mediaStreams, null, MediaStreamType.Audio, true);
}
+
+ state.AllMediaStreams = mediaStreams;
}
private async Task<MediaSourceInfo> GetChannelMediaInfo(string id,
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index 10543351b..53cc41501 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);
}
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index c6f454447..1d3ff939a 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -38,6 +38,8 @@ namespace MediaBrowser.Api.Playback
public string InputContainer { get; set; }
+ public List<MediaStream> AllMediaStreams { get; set; }
+
public MediaStream AudioStream { get; set; }
public MediaStream VideoStream { get; set; }
public MediaStream SubtitleStream { get; set; }
@@ -78,6 +80,7 @@ namespace MediaBrowser.Api.Playback
SupportedAudioCodecs = new List<string>();
PlayableStreamFileNames = new List<string>();
RemoteHttpHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+ AllMediaStreams = new List<MediaStream>();
}
public string InputAudioSync { get; set; }
diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs
index f7696e963..dc5799239 100644
--- a/MediaBrowser.Api/Subtitles/SubtitleService.cs
+++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs
@@ -9,8 +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;
@@ -91,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
@@ -106,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))
@@ -133,7 +205,7 @@ namespace MediaBrowser.Api.Subtitles
request.Index,
request.Format,
request.StartPositionTicks,
- null,
+ request.EndPositionTicks,
CancellationToken.None).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs
index d12b3598c..533f4ecf4 100644
--- a/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs
@@ -193,11 +193,12 @@ namespace MediaBrowser.Dlna.Profiles
}
};
- SoftSubtitleProfiles = new[]
+ SubtitleProfiles = new[]
{
new SubtitleProfile
{
- Format = "srt"
+ Format = "srt",
+ Method = SubtitleDeliveryMethod.External
}
};
}
diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
index b90c906fb..3dc1967dd 100644
--- a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
@@ -339,11 +339,12 @@ namespace MediaBrowser.Dlna.Profiles
}
};
- SoftSubtitleProfiles = new[]
+ SubtitleProfiles = new[]
{
new SubtitleProfile
{
- Format = "smi"
+ Format = "smi",
+ Method = SubtitleDeliveryMethod.External
}
};
}
diff --git a/MediaBrowser.Dlna/Profiles/Windows81Profile.cs b/MediaBrowser.Dlna/Profiles/Windows81Profile.cs
index 029fefc64..20d0834e1 100644
--- a/MediaBrowser.Dlna/Profiles/Windows81Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/Windows81Profile.cs
@@ -155,11 +155,12 @@ namespace MediaBrowser.Dlna.Profiles
}
};
- ExternalSubtitleProfiles = new[]
+ SubtitleProfiles = new[]
{
new SubtitleProfile
{
- Format = "ttml"
+ Format = "ttml",
+ Method = SubtitleDeliveryMethod.External
}
};
}
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Android.xml b/MediaBrowser.Dlna/Profiles/Xml/Android.xml
index b7a6cc19c..efab21021 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Android.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Android.xml
@@ -65,6 +65,4 @@
</CodecProfile>
</CodecProfiles>
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml
index 6aafbe86e..164ea943d 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Default.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml
@@ -35,6 +35,4 @@
<ContainerProfiles />
<CodecProfiles />
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
index 28fe6e0c9..9a4322b68 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
@@ -39,6 +39,4 @@
<ContainerProfiles />
<CodecProfiles />
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
index f0cf1e96c..ee18a5efa 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
@@ -73,6 +73,4 @@
</CodecProfile>
</CodecProfiles>
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
index 775c7e466..43516a378 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
@@ -39,6 +39,4 @@
<ContainerProfiles />
<CodecProfiles />
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
index 1461c2255..1d63d3885 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
@@ -45,6 +45,4 @@
<ContainerProfiles />
<CodecProfiles />
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
index 5859b2439..2ae5524fa 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
@@ -68,8 +68,7 @@
</CodecProfile>
</CodecProfiles>
<ResponseProfiles />
- <SoftSubtitleProfiles>
- <SubtitleProfile format="srt" />
- </SoftSubtitleProfiles>
- <ExternalSubtitleProfiles />
+ <SubtitleProfiles>
+ <SubtitleProfile format="srt" method="External" />
+ </SubtitleProfiles>
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
index 28f170bc0..b8edd8ff5 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
@@ -106,8 +106,7 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles>
- <SubtitleProfile format="smi" />
- </SoftSubtitleProfiles>
- <ExternalSubtitleProfiles />
+ <SubtitleProfiles>
+ <SubtitleProfile format="smi" method="External" />
+ </SubtitleProfiles>
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
index 2e32b77c6..c3c13cdc3 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
@@ -71,6 +71,4 @@
</CodecProfile>
</CodecProfiles>
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
index 87ba6e33b..d48fc34b1 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
@@ -99,6 +99,4 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
index 698bb44b1..319936e0a 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
@@ -107,6 +107,4 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
index f07536fcb..541ecf828 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
@@ -110,6 +110,4 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
index a99e4fa1e..a99dc6b4e 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
@@ -93,6 +93,4 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
index 3d4661621..40e55e98a 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
@@ -93,6 +93,4 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
index 55f89e3eb..4499b905d 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
@@ -93,6 +93,4 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
index 5d12b65c8..4e0231a53 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
@@ -78,6 +78,4 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml b/MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml
index 1847d844f..dec3d02ef 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml
@@ -62,8 +62,7 @@
</CodecProfile>
</CodecProfiles>
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles>
- <SubtitleProfile format="ttml" />
- </ExternalSubtitleProfiles>
+ <SubtitleProfiles>
+ <SubtitleProfile format="ttml" method="External" />
+ </SubtitleProfiles>
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml b/MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml
index 12b7fe9c9..7c3414b25 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml
@@ -76,6 +76,4 @@
</CodecProfile>
</CodecProfiles>
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
index f3e153130..b629fa518 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
@@ -100,6 +100,4 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
index 7e057a3f9..5f86a94a9 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
@@ -90,6 +90,4 @@
<Conditions />
</ResponseProfile>
</ResponseProfiles>
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
index d09911308..40ad2bc78 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
@@ -45,6 +45,4 @@
<ContainerProfiles />
<CodecProfiles />
<ResponseProfiles />
- <SoftSubtitleProfiles />
- <ExternalSubtitleProfiles />
</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs
index 630e7fa60..5366a538c 100644
--- a/MediaBrowser.Model/Dlna/DeviceProfile.cs
+++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs
@@ -90,8 +90,7 @@ namespace MediaBrowser.Model.Dlna
public CodecProfile[] CodecProfiles { get; set; }
public ResponseProfile[] ResponseProfiles { get; set; }
- public SubtitleProfile[] SoftSubtitleProfiles { get; set; }
- public SubtitleProfile[] ExternalSubtitleProfiles { get; set; }
+ public SubtitleProfile[] SubtitleProfiles { get; set; }
public DeviceProfile()
{
@@ -100,9 +99,6 @@ namespace MediaBrowser.Model.Dlna
ResponseProfiles = new ResponseProfile[] { };
CodecProfiles = new CodecProfile[] { };
ContainerProfiles = new ContainerProfile[] { };
-
- SoftSubtitleProfiles = new SubtitleProfile[] { };
- ExternalSubtitleProfiles = new SubtitleProfile[] { };
XmlRootAttributes = new XmlAttribute[] { };
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 22e817de1..72bf88b70 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -518,7 +518,7 @@ namespace MediaBrowser.Model.Dlna
{
// See if the device can retrieve the subtitles externally
bool supportsSubsExternally = options.Context == EncodingContext.Streaming &&
- ContainsSubtitleFormat(options.Profile.ExternalSubtitleProfiles, _serverTextSubtitleOutputs);
+ ContainsSubtitleFormat(options.Profile.SubtitleProfiles, SubtitleDeliveryMethod.External, _serverTextSubtitleOutputs);
if (supportsSubsExternally)
{
@@ -526,7 +526,7 @@ namespace MediaBrowser.Model.Dlna
}
// See if the device can retrieve the subtitles externally
- bool supportsEmbedded = ContainsSubtitleFormat(options.Profile.SoftSubtitleProfiles, _serverTextSubtitleOutputs);
+ bool supportsEmbedded = ContainsSubtitleFormat(options.Profile.SubtitleProfiles, SubtitleDeliveryMethod.Embed, _serverTextSubtitleOutputs);
if (supportsEmbedded)
{
@@ -547,11 +547,11 @@ namespace MediaBrowser.Model.Dlna
return codec;
}
- private bool ContainsSubtitleFormat(SubtitleProfile[] profiles, string[] formats)
+ private bool ContainsSubtitleFormat(SubtitleProfile[] profiles, SubtitleDeliveryMethod method, string[] formats)
{
foreach (SubtitleProfile profile in profiles)
{
- if (ListHelper.ContainsIgnoreCase(formats, profile.Format))
+ if (method == profile.Method && ListHelper.ContainsIgnoreCase(formats, profile.Format))
{
return true;
}
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 4f02d6450..f299a30c9 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -476,6 +476,10 @@ namespace MediaBrowser.Model.Dlna
/// <summary>
/// The external
/// </summary>
- External = 2
+ External = 2,
+ /// <summary>
+ /// The HLS
+ /// </summary>
+ Hls = 3
}
}
diff --git a/MediaBrowser.Model/Dlna/SubtitleProfile.cs b/MediaBrowser.Model/Dlna/SubtitleProfile.cs
index 7aa5e1771..189515835 100644
--- a/MediaBrowser.Model/Dlna/SubtitleProfile.cs
+++ b/MediaBrowser.Model/Dlna/SubtitleProfile.cs
@@ -9,5 +9,8 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("protocol")]
public string Protocol { get; set; }
+
+ [XmlAttribute("method")]
+ public SubtitleDeliveryMethod Method { get; set; }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 8ffe8aa63..ad2b50365 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -550,24 +550,28 @@ namespace MediaBrowser.Server.Implementations.LiveTv
};
}
- if (!string.IsNullOrEmpty(info.Path))
- {
- item.Path = info.Path;
- }
- else if (!string.IsNullOrEmpty(info.Url))
- {
- item.Path = info.Url;
- }
-
isNew = true;
}
item.RecordingInfo = info;
item.ServiceName = serviceName;
+ var originalPath = item.Path;
+
+ if (!string.IsNullOrEmpty(info.Path))
+ {
+ item.Path = info.Path;
+ }
+ else if (!string.IsNullOrEmpty(info.Url))
+ {
+ item.Path = info.Url;
+ }
+
+ var pathChanged = !string.Equals(originalPath, item.Path);
+
await item.RefreshMetadata(new MetadataRefreshOptions
{
- ForceSave = isNew
+ ForceSave = isNew || pathChanged
}, cancellationToken);