commit
3c33e1bb4b
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -456,7 +456,7 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <returns>IEnumerable<Folder>.</returns>
|
/// <returns>IEnumerable<Folder>.</returns>
|
||||||
IEnumerable<Folder> GetCollectionFolders(BaseItem item);
|
List<Folder> GetCollectionFolders(BaseItem item);
|
||||||
|
|
||||||
LibraryOptions GetLibraryOptions(BaseItem item);
|
LibraryOptions GetLibraryOptions(BaseItem item);
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(""", "'");
|
.Replace(""", "'");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user