fixes #887 - Support ttml subtitle output

This commit is contained in:
Luke Pulverenti
2014-08-05 19:59:24 -04:00
parent 7e25c857a5
commit 3ba6364f25
35 changed files with 333 additions and 96 deletions

View File

@@ -2,6 +2,7 @@
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Session;
using System;
using System.Collections.Generic;
@@ -9,7 +10,7 @@ namespace MediaBrowser.Model.Dlna
{
public class StreamBuilder
{
private string[] _serverTextSubtitleOutputs = new string[] { "srt", "vtt" };
private readonly string[] _serverTextSubtitleOutputs = { "srt", "vtt", "ttml" };
public StreamInfo BuildAudioItem(AudioOptions options)
{
@@ -158,7 +159,7 @@ namespace MediaBrowser.Model.Dlna
if (all)
{
playlistItem.IsDirectStream = true;
playlistItem.PlayMethod = PlayMethod.DirectStream;
playlistItem.Container = item.Container;
return playlistItem;
@@ -179,7 +180,7 @@ namespace MediaBrowser.Model.Dlna
if (transcodingProfile != null)
{
playlistItem.IsDirectStream = false;
playlistItem.PlayMethod = PlayMethod.Transcode;
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
playlistItem.Container = transcodingProfile.Container;
@@ -252,12 +253,12 @@ namespace MediaBrowser.Model.Dlna
if (directPlay != null)
{
playlistItem.IsDirectStream = true;
playlistItem.PlayMethod = PlayMethod.DirectStream;
playlistItem.Container = item.Container;
if (subtitleStream != null)
{
playlistItem.SubtitleDeliveryMethod = GetDirectStreamSubtitleDeliveryMethod(subtitleStream, options);
playlistItem.SubtitleDeliveryMethod = GetSubtitleDeliveryMethod(subtitleStream, options);
}
return playlistItem;
@@ -279,10 +280,10 @@ namespace MediaBrowser.Model.Dlna
{
if (subtitleStream != null)
{
playlistItem.SubtitleDeliveryMethod = GetTranscodedSubtitleDeliveryMethod(subtitleStream, options);
playlistItem.SubtitleDeliveryMethod = GetSubtitleDeliveryMethod(subtitleStream, options);
}
playlistItem.IsDirectStream = false;
playlistItem.PlayMethod = PlayMethod.Transcode;
playlistItem.Container = transcodingProfile.Container;
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
@@ -499,9 +500,9 @@ namespace MediaBrowser.Model.Dlna
return false;
}
SubtitleDeliveryMethod subtitleMethod = GetDirectStreamSubtitleDeliveryMethod(subtitleStream, options);
SubtitleDeliveryMethod subtitleMethod = GetSubtitleDeliveryMethod(subtitleStream, options);
if (subtitleMethod != SubtitleDeliveryMethod.External && subtitleMethod != SubtitleDeliveryMethod.Direct)
if (subtitleMethod != SubtitleDeliveryMethod.External && subtitleMethod != SubtitleDeliveryMethod.Embed)
{
return false;
}
@@ -510,34 +511,7 @@ namespace MediaBrowser.Model.Dlna
return IsAudioEligibleForDirectPlay(item, maxBitrate);
}
private SubtitleDeliveryMethod GetDirectStreamSubtitleDeliveryMethod(MediaStream subtitleStream,
VideoOptions options)
{
if (subtitleStream.IsTextSubtitleStream)
{
string subtitleFormat = NormalizeSubtitleFormat(subtitleStream.Codec);
bool supportsDirect = ContainsSubtitleFormat(options.Profile.SoftSubtitleProfiles, new[] { subtitleFormat });
if (supportsDirect)
{
return SubtitleDeliveryMethod.Direct;
}
// See if the device can retrieve the subtitles externally
bool supportsSubsExternally = options.Context == EncodingContext.Streaming &&
ContainsSubtitleFormat(options.Profile.ExternalSubtitleProfiles, _serverTextSubtitleOutputs);
if (supportsSubsExternally)
{
return SubtitleDeliveryMethod.External;
}
}
return SubtitleDeliveryMethod.Encode;
}
private SubtitleDeliveryMethod GetTranscodedSubtitleDeliveryMethod(MediaStream subtitleStream,
private SubtitleDeliveryMethod GetSubtitleDeliveryMethod(MediaStream subtitleStream,
VideoOptions options)
{
if (subtitleStream.IsTextSubtitleStream)

View File

@@ -3,6 +3,7 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Session;
using System;
using System.Collections.Generic;
@@ -15,7 +16,7 @@ namespace MediaBrowser.Model.Dlna
{
public string ItemId { get; set; }
public bool IsDirectStream { get; set; }
public PlayMethod PlayMethod { get; set; }
public DlnaProfileType MediaType { get; set; }
@@ -59,6 +60,7 @@ namespace MediaBrowser.Model.Dlna
public MediaSourceInfo MediaSource { get; set; }
public SubtitleDeliveryMethod SubtitleDeliveryMethod { get; set; }
public string SubtitleFormat { get; set; }
public string MediaSourceId
{
@@ -68,6 +70,11 @@ namespace MediaBrowser.Model.Dlna
}
}
public bool IsDirectStream
{
get { return PlayMethod == PlayMethod.DirectStream; }
}
public string ToUrl(string baseUrl)
{
return ToDlnaUrl(baseUrl);
@@ -124,6 +131,32 @@ namespace MediaBrowser.Model.Dlna
return string.Format("Params={0}", string.Join(";", list.ToArray()));
}
public string ToSubtitleUrl(string baseUrl)
{
if (SubtitleDeliveryMethod != SubtitleDeliveryMethod.External)
{
return null;
}
if (!SubtitleStreamIndex.HasValue)
{
return null;
}
// HLS will preserve timestamps so we can just grab the full subtitle stream
long startPositionTicks = StringHelper.EqualsIgnoreCase(Protocol, "hls")
? 0
: StartPositionTicks;
return string.Format("{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}",
baseUrl,
ItemId,
MediaSourceId,
StringHelper.ToStringCultureInvariant(SubtitleStreamIndex.Value),
StringHelper.ToStringCultureInvariant(startPositionTicks),
SubtitleFormat);
}
/// <summary>
/// Returns the audio stream that will be used
/// </summary>
@@ -437,16 +470,12 @@ namespace MediaBrowser.Model.Dlna
/// </summary>
Encode = 0,
/// <summary>
/// Internal format is supported natively
/// </summary>
Direct = 1,
/// <summary>
/// The embed
/// </summary>
Embed = 2,
Embed = 1,
/// <summary>
/// The external
/// </summary>
External = 3
External = 2
}
}

View File

@@ -1,8 +1,13 @@

using System.Xml.Serialization;
namespace MediaBrowser.Model.Dlna
{
public class SubtitleProfile
{
[XmlAttribute("format")]
public string Format { get; set; }
[XmlAttribute("protocol")]
public string Protocol { get; set; }
}
}
}

View File

@@ -525,6 +525,12 @@ namespace MediaBrowser.Model.Dto
return IsType(type.Name);
}
/// <summary>
/// Gets or sets a value indicating whether [supports playlists].
/// </summary>
/// <value><c>true</c> if [supports playlists]; otherwise, <c>false</c>.</value>
public bool SupportsPlaylists { get; set; }
/// <summary>
/// Determines whether the specified type is type.
/// </summary>
@@ -631,12 +637,6 @@ namespace MediaBrowser.Model.Dto
/// <value>The type of the media.</value>
public string MediaType { get; set; }
/// <summary>
/// Gets or sets the overview HTML.
/// </summary>
/// <value>The overview HTML.</value>
public string OverviewHtml { get; set; }
/// <summary>
/// Gets or sets the end date.
/// </summary>

View File

@@ -8,5 +8,6 @@
public const string VTT = "vtt";
public const string SUB = "sub";
public const string SMI = "smi";
public const string TTML = "ttml";
}
}