Merge pull request #2430 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2017-01-29 18:57:01 -05:00 committed by GitHub
commit 3c33e1bb4b
17 changed files with 162 additions and 47 deletions

View File

@ -501,7 +501,7 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentNullException("type"); throw new ArgumentNullException("type");
} }
if (key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath)) if (ConfigurationManager.Configuration.EnableLocalizedGuids && key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath))
{ {
// Try to normalize paths located underneath program-data in an attempt to make them more portable // Try to normalize paths located underneath program-data in an attempt to make them more portable
key = key.Substring(ConfigurationManager.ApplicationPaths.ProgramDataPath.Length) key = key.Substring(ConfigurationManager.ApplicationPaths.ProgramDataPath.Length)
@ -1927,11 +1927,18 @@ namespace Emby.Server.Implementations.Library
return ItemRepository.RetrieveItem(id); return ItemRepository.RetrieveItem(id);
} }
public IEnumerable<Folder> GetCollectionFolders(BaseItem item) public List<Folder> GetCollectionFolders(BaseItem item)
{ {
while (!(item.GetParent() is AggregateFolder) && item.GetParent() != null) while (item != null)
{ {
item = item.GetParent(); var parent = item.GetParent();
if (parent == null || parent is AggregateFolder)
{
break;
}
item = parent;
} }
if (item == null) if (item == null)
@ -1941,7 +1948,8 @@ namespace Emby.Server.Implementations.Library
return GetUserRootFolder().Children return GetUserRootFolder().Children
.OfType<Folder>() .OfType<Folder>()
.Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path, StringComparer.OrdinalIgnoreCase)); .Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path, StringComparer.OrdinalIgnoreCase))
.ToList();
} }
public LibraryOptions GetLibraryOptions(BaseItem item) public LibraryOptions GetLibraryOptions(BaseItem item)

View File

@ -74,20 +74,21 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
return new MusicArtist(); return new MusicArtist();
} }
if (_config.Configuration.EnableSimpleArtistDetection) return null;
{ //if (_config.Configuration.EnableSimpleArtistDetection)
return null; //{
} // return null;
//}
// Avoid mis-identifying top folders //// Avoid mis-identifying top folders
if (args.Parent.IsRoot) return null; //if (args.Parent.IsRoot) return null;
var directoryService = args.DirectoryService; //var directoryService = args.DirectoryService;
var albumResolver = new MusicAlbumResolver(_logger, _fileSystem, _libraryManager); //var albumResolver = new MusicAlbumResolver(_logger, _fileSystem, _libraryManager);
// If we contain an album assume we are an artist folder //// If we contain an album assume we are an artist folder
return args.FileSystemChildren.Where(i => i.IsDirectory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService, args.GetLibraryOptions())) ? new MusicArtist() : null; //return args.FileSystemChildren.Where(i => i.IsDirectory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService, args.GetLibraryOptions())) ? new MusicArtist() : null;
} }
} }

View File

@ -154,7 +154,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
var durationParam = " -t " + _mediaEncoder.GetTimeParameter(duration.Ticks); var durationParam = " -t " + _mediaEncoder.GetTimeParameter(duration.Ticks);
var inputModifiers = "-fflags +genpts -async 1 -vsync -1"; var inputModifiers = "-fflags +genpts -async 1 -vsync -1";
var commandLineArgs = "-i \"{0}\"{4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; var mapArgs = string.Equals(OutputFormat, "mkv", StringComparison.OrdinalIgnoreCase) ? "-map 0" : "-sn";
var commandLineArgs = "-i \"{0}\"{4} " + mapArgs + " {2} -map_metadata -1 -threads 0 {3} -y \"{1}\"";
long startTimeTicks = 0; long startTimeTicks = 0;
//if (mediaSource.DateLiveStreamOpened.HasValue) //if (mediaSource.DateLiveStreamOpened.HasValue)

View File

@ -223,6 +223,10 @@ namespace MediaBrowser.Api.Playback
{ {
args += " -map -0:s"; args += " -map -0:s";
} }
else if (state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Embed)
{
args += string.Format(" -map 0:{0}", state.SubtitleStream.Index);
}
else if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) else if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
{ {
args += " -map 1:0 -sn"; args += " -map 1:0 -sn";
@ -1797,6 +1801,10 @@ namespace MediaBrowser.Api.Playback
videoRequest.RequireAvc = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); videoRequest.RequireAvc = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
} }
} }
else if (i == 30)
{
request.SubtitleCodec = val;
}
} }
} }
@ -1915,6 +1923,13 @@ namespace MediaBrowser.Api.Playback
?? state.SupportedAudioCodecs.FirstOrDefault(); ?? state.SupportedAudioCodecs.FirstOrDefault();
} }
if (!string.IsNullOrWhiteSpace(request.SubtitleCodec))
{
state.SupportedSubtitleCodecs = request.SubtitleCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
state.Request.SubtitleCodec = state.SupportedSubtitleCodecs.FirstOrDefault(i => MediaEncoder.CanEncodeToSubtitleCodec(i))
?? state.SupportedSubtitleCodecs.FirstOrDefault();
}
var item = LibraryManager.GetItemById(request.Id); var item = LibraryManager.GetItemById(request.Id);
state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase); state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
@ -2109,6 +2124,7 @@ namespace MediaBrowser.Api.Playback
state.VideoStream = GetMediaStream(mediaStreams, videoRequest.VideoStreamIndex, MediaStreamType.Video); state.VideoStream = GetMediaStream(mediaStreams, videoRequest.VideoStreamIndex, MediaStreamType.Video);
state.SubtitleStream = GetMediaStream(mediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false); state.SubtitleStream = GetMediaStream(mediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false);
state.SubtitleDeliveryMethod = videoRequest.SubtitleMethod;
state.AudioStream = GetMediaStream(mediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio); state.AudioStream = GetMediaStream(mediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio);
if (state.SubtitleStream != null && !state.SubtitleStream.IsExternal) if (state.SubtitleStream != null && !state.SubtitleStream.IsExternal)

View File

@ -9,6 +9,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Common.IO; using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO; using MediaBrowser.Controller.IO;
@ -111,7 +112,12 @@ namespace MediaBrowser.Api.Playback.Progressive
var inputModifier = GetInputModifier(state); var inputModifier = GetInputModifier(state);
return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -map_chapters -1 -threads {5} {6}{7} -y \"{8}\"", var subtitleArguments = state.SubtitleStream != null &&
state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Embed
? GetSubtitleArguments(state)
: string.Empty;
return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -map_chapters -1 -threads {5} {6}{7}{8} -y \"{9}\"",
inputModifier, inputModifier,
GetInputArgument(state), GetInputArgument(state),
keyFrame, keyFrame,
@ -119,11 +125,29 @@ namespace MediaBrowser.Api.Playback.Progressive
GetVideoArguments(state, videoCodec), GetVideoArguments(state, videoCodec),
threads, threads,
GetAudioArguments(state), GetAudioArguments(state),
subtitleArguments,
format, format,
outputPath outputPath
).Trim(); ).Trim();
} }
private string GetSubtitleArguments(StreamState state)
{
var format = state.SupportedSubtitleCodecs.FirstOrDefault();
string codec;
if (string.IsNullOrWhiteSpace(format) || string.Equals(format, state.SubtitleStream.Codec, StringComparison.OrdinalIgnoreCase))
{
codec = "copy";
}
else
{
codec = format;
}
return " -codec:s:0 " + codec;
}
/// <summary> /// <summary>
/// Gets video arguments to pass to ffmpeg /// Gets video arguments to pass to ffmpeg
/// </summary> /// </summary>

View File

@ -28,6 +28,8 @@ namespace MediaBrowser.Api.Playback
[ApiMember(Name = "AudioCodec", Description = "Optional. Specify a audio codec to encode to, e.g. mp3. If omitted the server will auto-select using the url's extension. Options: aac, mp3, vorbis, wma.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "AudioCodec", Description = "Optional. Specify a audio codec to encode to, e.g. mp3. If omitted the server will auto-select using the url's extension. Options: aac, mp3, vorbis, wma.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string AudioCodec { get; set; } public string AudioCodec { get; set; }
public string SubtitleCodec { get; set; }
/// <summary> /// <summary>
/// Gets or sets the start time ticks. /// Gets or sets the start time ticks.
/// </summary> /// </summary>

View File

@ -47,6 +47,7 @@ namespace MediaBrowser.Api.Playback
public MediaStream AudioStream { get; set; } public MediaStream AudioStream { get; set; }
public MediaStream VideoStream { get; set; } public MediaStream VideoStream { get; set; }
public MediaStream SubtitleStream { get; set; } public MediaStream SubtitleStream { get; set; }
public SubtitleDeliveryMethod SubtitleDeliveryMethod { get; set; }
/// <summary> /// <summary>
/// Gets or sets the iso mount. /// Gets or sets the iso mount.
@ -124,6 +125,7 @@ namespace MediaBrowser.Api.Playback
public string OutputAudioSync = "1"; public string OutputAudioSync = "1";
public string OutputVideoSync = "-1"; public string OutputVideoSync = "-1";
public List<string> SupportedSubtitleCodecs { get; set; }
public List<string> SupportedAudioCodecs { get; set; } public List<string> SupportedAudioCodecs { get; set; }
public List<string> SupportedVideoCodecs { get; set; } public List<string> SupportedVideoCodecs { get; set; }
public string UserAgent { get; set; } public string UserAgent { get; set; }
@ -133,6 +135,7 @@ namespace MediaBrowser.Api.Playback
{ {
_mediaSourceManager = mediaSourceManager; _mediaSourceManager = mediaSourceManager;
_logger = logger; _logger = logger;
SupportedSubtitleCodecs = new List<string>();
SupportedAudioCodecs = new List<string>(); SupportedAudioCodecs = new List<string>();
SupportedVideoCodecs = new List<string>(); SupportedVideoCodecs = new List<string>();
PlayableStreamFileNames = new List<string>(); PlayableStreamFileNames = new List<string>();

View File

@ -189,24 +189,10 @@ namespace MediaBrowser.Api
result.Series = hasSeries.SeriesName; result.Series = hasSeries.SeriesName;
} }
var season = item as Season;
if (season != null)
{
result.EpisodeCount = season.GetRecursiveChildren(i => i is Episode).Count;
}
var series = item as Series;
if (series != null)
{
result.EpisodeCount = series.GetRecursiveChildren(i => i is Episode).Count;
}
var album = item as MusicAlbum; var album = item as MusicAlbum;
if (album != null) if (album != null)
{ {
result.SongCount = album.Tracks.Count();
result.Artists = album.Artists.ToArray(); result.Artists = album.Artists.ToArray();
result.AlbumArtist = album.AlbumArtist; result.AlbumArtist = album.AlbumArtist;
} }

View File

@ -114,11 +114,11 @@ namespace MediaBrowser.Api
config.EnableStandaloneMusicKeys = true; config.EnableStandaloneMusicKeys = true;
config.EnableCaseSensitiveItemIds = true; config.EnableCaseSensitiveItemIds = true;
config.EnableFolderView = true; config.EnableFolderView = true;
config.EnableSimpleArtistDetection = true;
config.SkipDeserializationForBasicTypes = true; config.SkipDeserializationForBasicTypes = true;
config.SkipDeserializationForPrograms = true; config.SkipDeserializationForPrograms = true;
config.SkipDeserializationForAudio = true; config.SkipDeserializationForAudio = true;
config.EnableSeriesPresentationUniqueKey = true; config.EnableSeriesPresentationUniqueKey = true;
config.EnableLocalizedGuids = true;
} }
public void Post(UpdateStartupConfiguration request) public void Post(UpdateStartupConfiguration request)

View File

@ -456,7 +456,7 @@ namespace MediaBrowser.Controller.Library
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <returns>IEnumerable&lt;Folder&gt;.</returns> /// <returns>IEnumerable&lt;Folder&gt;.</returns>
IEnumerable<Folder> GetCollectionFolders(BaseItem item); List<Folder> GetCollectionFolders(BaseItem item);
LibraryOptions GetLibraryOptions(BaseItem item); LibraryOptions GetLibraryOptions(BaseItem item);

View File

@ -496,6 +496,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
return SupportsEncoder(codec); return SupportsEncoder(codec);
} }
public bool CanEncodeToSubtitleCodec(string codec)
{
// TODO
return true;
}
/// <summary> /// <summary>
/// Gets the encoder path. /// Gets the encoder path.
/// </summary> /// </summary>

View File

@ -47,6 +47,7 @@ namespace MediaBrowser.Model.Configuration
/// <value><c>true</c> if [use HTTPS]; otherwise, <c>false</c>.</value> /// <value><c>true</c> if [use HTTPS]; otherwise, <c>false</c>.</value>
public bool EnableHttps { get; set; } public bool EnableHttps { get; set; }
public bool EnableSeriesPresentationUniqueKey { get; set; } public bool EnableSeriesPresentationUniqueKey { get; set; }
public bool EnableLocalizedGuids { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value pointing to the file system where the ssl certiifcate is located.. /// Gets or sets the value pointing to the file system where the ssl certiifcate is located..
@ -189,7 +190,6 @@ namespace MediaBrowser.Model.Configuration
public string[] Migrations { get; set; } public string[] Migrations { get; set; }
public bool EnableChannelView { get; set; } public bool EnableChannelView { get; set; }
public bool EnableExternalContentInSuggestions { get; set; } public bool EnableExternalContentInSuggestions { get; set; }
public bool EnableSimpleArtistDetection { get; set; }
public int ImageExtractionTimeoutMs { get; set; } public int ImageExtractionTimeoutMs { get; set; }
/// <summary> /// <summary>
@ -201,6 +201,7 @@ namespace MediaBrowser.Model.Configuration
CodecsUsed = new string[] { }; CodecsUsed = new string[] { };
Migrations = new string[] { }; Migrations = new string[] { };
ImageExtractionTimeoutMs = 0; ImageExtractionTimeoutMs = 0;
EnableLocalizedGuids = true;
DisplaySpecialsWithinSeasons = true; DisplaySpecialsWithinSeasons = true;
EnableExternalContentInSuggestions = true; EnableExternalContentInSuggestions = true;

View File

@ -3,6 +3,7 @@
public interface ITranscoderSupport public interface ITranscoderSupport
{ {
bool CanEncodeToAudioCodec(string codec); bool CanEncodeToAudioCodec(string codec);
bool CanEncodeToSubtitleCodec(string codec);
} }
public class FullTranscoderSupport : ITranscoderSupport public class FullTranscoderSupport : ITranscoderSupport
@ -11,5 +12,9 @@
{ {
return true; return true;
} }
public bool CanEncodeToSubtitleCodec(string codec)
{
return true;
}
} }
} }

View File

@ -435,7 +435,7 @@ namespace MediaBrowser.Model.Dlna
if (subtitleStream != null) if (subtitleStream != null)
{ {
SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile.SubtitleProfiles, directPlay.Value); SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile.SubtitleProfiles, directPlay.Value, null, null);
playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method; playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method;
playlistItem.SubtitleFormat = subtitleProfile.Format; playlistItem.SubtitleFormat = subtitleProfile.Format;
@ -465,10 +465,11 @@ namespace MediaBrowser.Model.Dlna
if (subtitleStream != null) if (subtitleStream != null)
{ {
SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile.SubtitleProfiles, PlayMethod.Transcode); SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile.SubtitleProfiles, PlayMethod.Transcode, transcodingProfile.Protocol, transcodingProfile.Container);
playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method; playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method;
playlistItem.SubtitleFormat = subtitleProfile.Format; playlistItem.SubtitleFormat = subtitleProfile.Format;
playlistItem.SubtitleCodecs = new[] { subtitleProfile.Format };
} }
playlistItem.PlayMethod = PlayMethod.Transcode; playlistItem.PlayMethod = PlayMethod.Transcode;
@ -874,7 +875,7 @@ namespace MediaBrowser.Model.Dlna
{ {
if (subtitleStream != null) if (subtitleStream != null)
{ {
SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile.SubtitleProfiles, playMethod); SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile.SubtitleProfiles, playMethod, null, null);
if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed) if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed)
{ {
@ -886,11 +887,11 @@ namespace MediaBrowser.Model.Dlna
return IsAudioEligibleForDirectPlay(item, maxBitrate); return IsAudioEligibleForDirectPlay(item, maxBitrate);
} }
public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod) public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, string transcodingSubProtocol, string transcodingContainer)
{ {
if (playMethod != PlayMethod.Transcode && !subtitleStream.IsExternal) if (!subtitleStream.IsExternal && (playMethod != PlayMethod.Transcode || !string.Equals(transcodingSubProtocol, "hls", StringComparison.OrdinalIgnoreCase)))
{ {
// Look for supported embedded subs // Look for supported embedded subs of the same format
foreach (SubtitleProfile profile in subtitleProfiles) foreach (SubtitleProfile profile in subtitleProfiles)
{ {
if (!profile.SupportsLanguage(subtitleStream.Language)) if (!profile.SupportsLanguage(subtitleStream.Language))
@ -903,11 +904,40 @@ namespace MediaBrowser.Model.Dlna
continue; continue;
} }
if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(subtitleStream, profile, transcodingSubProtocol, transcodingContainer))
{
continue;
}
if (subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format) && StringHelper.EqualsIgnoreCase(profile.Format, subtitleStream.Codec)) if (subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format) && StringHelper.EqualsIgnoreCase(profile.Format, subtitleStream.Codec))
{ {
return profile; return profile;
} }
} }
// Look for supported embedded subs of a convertible format
foreach (SubtitleProfile profile in subtitleProfiles)
{
if (!profile.SupportsLanguage(subtitleStream.Language))
{
continue;
}
if (profile.Method != SubtitleDeliveryMethod.Embed)
{
continue;
}
if (playMethod == PlayMethod.Transcode && !IsSubtitleEmbedSupported(subtitleStream, profile, transcodingSubProtocol, transcodingContainer))
{
continue;
}
if (subtitleStream.IsTextSubtitleStream && subtitleStream.SupportsSubtitleConversionTo(profile.Format))
{
return profile;
}
}
} }
// Look for an external or hls profile that matches the stream type (text/graphical) and doesn't require conversion // Look for an external or hls profile that matches the stream type (text/graphical) and doesn't require conversion
@ -918,6 +948,28 @@ namespace MediaBrowser.Model.Dlna
}; };
} }
private static bool IsSubtitleEmbedSupported(MediaStream subtitleStream, SubtitleProfile subtitleProfile, string transcodingSubProtocol, string transcodingContainer)
{
if (string.Equals(transcodingContainer, "ts", StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (string.Equals(transcodingContainer, "mpegts", StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (string.Equals(transcodingContainer, "mp4", StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (string.Equals(transcodingContainer, "mkv", StringComparison.OrdinalIgnoreCase))
{
return true;
}
return false;
}
private static SubtitleProfile GetExternalSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, bool allowConversion) private static SubtitleProfile GetExternalSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, bool allowConversion)
{ {
foreach (SubtitleProfile profile in subtitleProfiles) foreach (SubtitleProfile profile in subtitleProfiles)

View File

@ -18,6 +18,7 @@ namespace MediaBrowser.Model.Dlna
public StreamInfo() public StreamInfo()
{ {
AudioCodecs = new string[] { }; AudioCodecs = new string[] { };
SubtitleCodecs = new string[] { };
} }
public string ItemId { get; set; } public string ItemId { get; set; }
@ -74,6 +75,7 @@ namespace MediaBrowser.Model.Dlna
public MediaSourceInfo MediaSource { get; set; } public MediaSourceInfo MediaSource { get; set; }
public string[] SubtitleCodecs { get; set; }
public SubtitleDeliveryMethod SubtitleDeliveryMethod { get; set; } public SubtitleDeliveryMethod SubtitleDeliveryMethod { get; set; }
public string SubtitleFormat { get; set; } public string SubtitleFormat { get; set; }
@ -268,6 +270,12 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("Tag", item.MediaSource.ETag ?? string.Empty)); list.Add(new NameValuePair("Tag", item.MediaSource.ETag ?? string.Empty));
list.Add(new NameValuePair("RequireAvc", item.RequireAvc.ToString().ToLower())); list.Add(new NameValuePair("RequireAvc", item.RequireAvc.ToString().ToLower()));
string subtitleCodecs = item.SubtitleCodecs.Length == 0 ?
string.Empty :
string.Join(",", item.SubtitleCodecs);
list.Add(new NameValuePair("SubtitleCodec", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Embed ? subtitleCodecs : string.Empty));
return list; return list;
} }
@ -354,7 +362,7 @@ namespace MediaBrowser.Model.Dlna
private SubtitleStreamInfo GetSubtitleStreamInfo(MediaStream stream, string baseUrl, string accessToken, long startPositionTicks, SubtitleProfile[] subtitleProfiles) private SubtitleStreamInfo GetSubtitleStreamInfo(MediaStream stream, string baseUrl, string accessToken, long startPositionTicks, SubtitleProfile[] subtitleProfiles)
{ {
SubtitleProfile subtitleProfile = StreamBuilder.GetSubtitleProfile(stream, subtitleProfiles, PlayMethod); SubtitleProfile subtitleProfile = StreamBuilder.GetSubtitleProfile(stream, subtitleProfiles, PlayMethod, SubProtocol, Container);
SubtitleStreamInfo info = new SubtitleStreamInfo SubtitleStreamInfo info = new SubtitleStreamInfo
{ {
IsForced = stream.IsForced, IsForced = stream.IsForced,

View File

@ -311,29 +311,31 @@ namespace MediaBrowser.Model.Entities
!StringHelper.EqualsIgnoreCase(codec, "dvb_subtitle"); !StringHelper.EqualsIgnoreCase(codec, "dvb_subtitle");
} }
public bool SupportsSubtitleConversionTo(string codec) public bool SupportsSubtitleConversionTo(string toCodec)
{ {
if (!IsTextSubtitleStream) if (!IsTextSubtitleStream)
{ {
return false; return false;
} }
var fromCodec = Codec;
// Can't convert from this // Can't convert from this
if (StringHelper.EqualsIgnoreCase(Codec, "ass")) if (StringHelper.EqualsIgnoreCase(fromCodec, "ass"))
{ {
return false; return false;
} }
if (StringHelper.EqualsIgnoreCase(Codec, "ssa")) if (StringHelper.EqualsIgnoreCase(fromCodec, "ssa"))
{ {
return false; return false;
} }
// Can't convert to this // Can't convert to this
if (StringHelper.EqualsIgnoreCase(codec, "ass")) if (StringHelper.EqualsIgnoreCase(toCodec, "ass"))
{ {
return false; return false;
} }
if (StringHelper.EqualsIgnoreCase(codec, "ssa")) if (StringHelper.EqualsIgnoreCase(toCodec, "ssa"))
{ {
return false; return false;
} }

View File

@ -457,7 +457,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
if (item is Video) if (item is Video)
{ {
var outline = (item.Tagline ?? item.Overview ?? string.Empty) var outline = (item.Tagline ?? string.Empty)
.StripHtml() .StripHtml()
.Replace("&quot;", "'"); .Replace("&quot;", "'");