2
0
Эх сурвалжийг харах

restore localized guids switch

Luke Pulverenti 8 жил өмнө
parent
commit
ab026ab2de

+ 13 - 5
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -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)

+ 11 - 10
Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs

@@ -74,20 +74,21 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
                 return new MusicArtist();
                 return new MusicArtist();
             }
             }
 
 
-            if (_config.Configuration.EnableSimpleArtistDetection)
-            {
-                return null;
-            }
+            return null;
+            //if (_config.Configuration.EnableSimpleArtistDetection)
+            //{
+            //    return null;
+            //}
 
 
-            // Avoid mis-identifying top folders
-            if (args.Parent.IsRoot) return null;
+            //// Avoid mis-identifying top folders
+            //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
-            return args.FileSystemChildren.Where(i => i.IsDirectory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService, args.GetLibraryOptions())) ? new MusicArtist() : null;
+            //// 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;
         }
         }
 
 
     }
     }

+ 16 - 0
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -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)

+ 25 - 1
MediaBrowser.Api/Playback/Progressive/VideoService.cs

@@ -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>

+ 2 - 0
MediaBrowser.Api/Playback/StreamRequest.cs

@@ -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>

+ 3 - 0
MediaBrowser.Api/Playback/StreamState.cs

@@ -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>();

+ 0 - 14
MediaBrowser.Api/SearchService.cs

@@ -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;
             }
             }

+ 1 - 1
MediaBrowser.Api/StartupWizardService.cs

@@ -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)

+ 1 - 1
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -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);
 
 

+ 6 - 0
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -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>

+ 2 - 1
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -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;

+ 5 - 0
MediaBrowser.Model/Dlna/ITranscoderSupport.cs

@@ -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;
+        }
     }
     }
 }
 }

+ 58 - 6
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -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)

+ 9 - 1
MediaBrowser.Model/Dlna/StreamInfo.cs

@@ -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,

+ 7 - 5
MediaBrowser.Model/Entities/MediaStream.cs

@@ -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;
             }
             }

+ 1 - 1
MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs

@@ -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;", "'");