mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-26 10:36:57 +01:00
fixes #887 - Support ttml subtitle output
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -8,5 +8,6 @@
|
||||
public const string VTT = "vtt";
|
||||
public const string SUB = "sub";
|
||||
public const string SMI = "smi";
|
||||
public const string TTML = "ttml";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user