diff options
Diffstat (limited to 'MediaBrowser.MediaEncoding')
15 files changed, 150 insertions, 172 deletions
diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs index 557f4d637..da96f3855 100644 --- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs +++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs @@ -1,4 +1,4 @@ -using BDInfo; +using BDInfo; using MediaBrowser.Model.Entities; using MediaBrowser.Model.MediaInfo; using System; @@ -32,7 +32,7 @@ namespace MediaBrowser.MediaEncoding.BdInfo { if (string.IsNullOrWhiteSpace(path)) { - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(path)); } var bdrom = new BDROM(path, _fileSystem, _textEncoding); diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index b68961889..578e9f264 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -51,7 +51,7 @@ namespace MediaBrowser.MediaEncoding.Encoder return false; } - _logger.LogInformation("ffmpeg info: {0}", output); + _logger.LogDebug("ffmpeg output: {Output}", output); if (output.IndexOf("Libav developers", StringComparison.OrdinalIgnoreCase) != -1) { @@ -160,10 +160,12 @@ namespace MediaBrowser.MediaEncoding.Encoder Arguments = arguments, IsHidden = true, ErrorDialog = false, - RedirectStandardOutput = true + RedirectStandardOutput = true, + // ffmpeg uses stderr to log info, don't show this + RedirectStandardError = true }); - _logger.LogInformation("Running {Path} {Arguments}", path, arguments); + _logger.LogDebug("Running {Path} {Arguments}", path, arguments); using (process) { @@ -175,7 +177,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } catch { - _logger.LogInformation("Killing process {path} {arguments}", path, arguments); + _logger.LogWarning("Killing process {Path} {Arguments}", path, arguments); // Hate having to do this try diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs index 9761de98f..1edc5c201 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs @@ -46,7 +46,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly ILogger _logger; private readonly IMediaSourceManager _mediaSourceManager; - public EncodingJob(ILogger logger, IMediaSourceManager mediaSourceManager) : + public EncodingJob(ILogger logger, IMediaSourceManager mediaSourceManager) : base(logger, mediaSourceManager, TranscodingJobType.Progressive) { _logger = logger; diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index 4e6ee89e1..34bc8d1b9 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -25,7 +25,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly IMediaEncoder _mediaEncoder; protected static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - + public EncodingJobFactory(ILogger logger, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager, IConfigurationManager config, IMediaEncoder mediaEncoder) { _logger = logger; @@ -255,7 +255,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (profile == null) { - // Don't use settings from the default profile. + // Don't use settings from the default profile. // Only use a specific profile if it was requested. return; } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index a93dd9742..b19271d11 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -70,7 +70,6 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly string _originalFFMpegPath; private readonly string _originalFFProbePath; private readonly int DefaultImageExtractionTimeoutMs; - private readonly IEnvironmentInfo _environmentInfo; public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, @@ -89,8 +88,7 @@ namespace MediaBrowser.MediaEncoding.Encoder IHttpClient httpClient, IZipClient zipClient, IProcessFactory processFactory, - int defaultImageExtractionTimeoutMs, - IEnvironmentInfo environmentInfo) + int defaultImageExtractionTimeoutMs) { _logger = logger; _jsonSerializer = jsonSerializer; @@ -107,46 +105,13 @@ namespace MediaBrowser.MediaEncoding.Encoder _zipClient = zipClient; _processFactory = processFactory; DefaultImageExtractionTimeoutMs = defaultImageExtractionTimeoutMs; - _environmentInfo = environmentInfo; FFProbePath = ffProbePath; FFMpegPath = ffMpegPath; _originalFFProbePath = ffProbePath; _originalFFMpegPath = ffMpegPath; - _hasExternalEncoder = hasExternalEncoder; } - private readonly object _logLock = new object(); - public void SetLogFilename(string name) - { - lock (_logLock) - { - try - { - _environmentInfo.SetProcessEnvironmentVariable("FFREPORT", "file=" + name + ":level=32"); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error setting FFREPORT environment variable"); - } - } - } - - public void ClearLogFilename() - { - lock (_logLock) - { - try - { - _environmentInfo.SetProcessEnvironmentVariable("FFREPORT", null); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error setting FFREPORT environment variable"); - } - } - } - public string EncoderLocationType { get @@ -246,7 +211,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { if (string.IsNullOrWhiteSpace(path)) { - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(path)); } if (!FileSystem.FileExists(path) && !FileSystem.DirectoryExists(path)) @@ -362,7 +327,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private Tuple<string, string> GetPathsFromDirectory(string path) { - // Since we can't predict the file extension, first try directly within the folder + // Since we can't predict the file extension, first try directly within the folder // If that doesn't pan out, then do a recursive search var files = FileSystem.GetFilePaths(path); @@ -525,7 +490,7 @@ namespace MediaBrowser.MediaEncoding.Encoder CreateNoWindow = true, UseShellExecute = false, - // Must consume both or ffmpeg may hang due to deadlocks. See comments below. + // Must consume both or ffmpeg may hang due to deadlocks. See comments below. RedirectStandardOutput = true, FileName = FFProbePath, Arguments = string.Format(args, probeSizeArgument, inputPath).Trim(), @@ -642,13 +607,13 @@ namespace MediaBrowser.MediaEncoding.Encoder { if (string.IsNullOrEmpty(inputPath)) { - throw new ArgumentNullException("inputPath"); + throw new ArgumentNullException(nameof(inputPath)); } var tempExtractPath = Path.Combine(ConfigurationManager.ApplicationPaths.TempDirectory, Guid.NewGuid() + ".jpg"); FileSystem.CreateDirectory(FileSystem.GetDirectoryName(tempExtractPath)); - // apply some filters to thumbnail extracted below (below) crop any black lines that we made and get the correct ar then scale to width 600. + // apply some filters to thumbnail extracted below (below) crop any black lines that we made and get the correct ar then scale to width 600. // This filter chain may have adverse effects on recorded tv thumbnails if ar changes during presentation ex. commercials @ diff ar var vf = "scale=600:trunc(600/dar/2)*2"; @@ -676,7 +641,7 @@ namespace MediaBrowser.MediaEncoding.Encoder break; } } - + var mapArg = imageStreamIndex.HasValue ? (" -map 0:v:" + imageStreamIndex.Value.ToString(CultureInfo.InvariantCulture)) : string.Empty; var enableThumbnail = !new List<string> { "wtv" }.Contains(container ?? string.Empty, StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs index 396c85e21..12d906bb2 100644 --- a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs +++ b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.MediaEncoding.Probing { if (result == null) { - throw new ArgumentNullException("result"); + throw new ArgumentNullException(nameof(result)); } if (result.format != null && result.format.tags != null) diff --git a/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs b/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs index eef273250..350a2e3e5 100644 --- a/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs +++ b/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs @@ -149,7 +149,7 @@ namespace MediaBrowser.MediaEncoding.Probing /// </summary> /// <value>The bits_per_raw_sample.</value> public int bits_per_raw_sample { get; set; } - + /// <summary> /// Gets or sets the r_frame_rate. /// </summary> diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 5367a87f7..2d3352f64 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -132,7 +132,7 @@ namespace MediaBrowser.MediaEncoding.Probing if (!string.IsNullOrWhiteSpace(iTunEXTC)) { var parts = iTunEXTC.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); - // Example + // Example // mpaa|G|100|For crude humor if (parts.Length > 1) { @@ -423,7 +423,7 @@ namespace MediaBrowser.MediaEncoding.Probing Type = PersonType.Writer }); } - + } else if (string.Equals(key, "producers", StringComparison.OrdinalIgnoreCase)) { @@ -619,7 +619,7 @@ namespace MediaBrowser.MediaEncoding.Probing else if (string.Equals(stream.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase)) { // How to differentiate between video and embedded image? - // The only difference I've seen thus far is presence of codec tag, also embedded images have high (unusual) framerates + // The only difference I've seen thus far is presence of codec tag, also embedded images have high (unusual) framerates if (!string.IsNullOrWhiteSpace(stream.CodecTag)) { stream.Type = MediaStreamType.Video; @@ -1054,7 +1054,7 @@ namespace MediaBrowser.MediaEncoding.Probing /// <returns>System.String[][].</returns> private IEnumerable<string> Split(string val, bool allowCommaDelimiter) { - // Only use the comma as a delimeter if there are no slashes or pipes. + // Only use the comma as a delimeter if there are no slashes or pipes. // We want to be careful not to split names that have commas in them var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i) != -1) ? _nameDelimiters : @@ -1301,7 +1301,7 @@ namespace MediaBrowser.MediaEncoding.Probing // OR -> COMMENT. SUBTITLE: DESCRIPTION // e.g. -> 4/13. The Doctor's Wife: Science fiction drama. When he follows a Time Lord distress signal, the Doctor puts Amy, Rory and his beloved TARDIS in grave danger. Also in HD. [AD,S] // e.g. -> CBeebies Bedtime Hour. The Mystery: Animated adventures of two friends who live on an island in the middle of the big city. Some of Abney and Teal's favourite objects are missing. [S] - if (String.IsNullOrWhiteSpace(subTitle) && !String.IsNullOrWhiteSpace(description) && description.Substring(0, Math.Min(description.Length, MaxSubtitleDescriptionExtractionLength)).Contains(":")) // Check within the Subtitle size limit, otherwise from description it can get too long creating an invalid filename + if (string.IsNullOrWhiteSpace(subTitle) && !string.IsNullOrWhiteSpace(description) && description.Substring(0, Math.Min(description.Length, MaxSubtitleDescriptionExtractionLength)).Contains(":")) // Check within the Subtitle size limit, otherwise from description it can get too long creating an invalid filename { string[] parts = description.Split(':'); if (parts.Length > 0) @@ -1315,7 +1315,7 @@ namespace MediaBrowser.MediaEncoding.Probing video.IndexNumber = int.Parse(numbers[0].Replace(".", "").Split('/')[0]); int totalEpisodesInSeason = int.Parse(numbers[0].Replace(".", "").Split('/')[1]); - description = String.Join(" ", numbers, 1, numbers.Length - 1).Trim(); // Skip the first, concatenate the rest, clean up spaces and save it + description = string.Join(" ", numbers, 1, numbers.Length - 1).Trim(); // Skip the first, concatenate the rest, clean up spaces and save it } else throw new Exception(); // Switch to default parsing @@ -1323,7 +1323,7 @@ namespace MediaBrowser.MediaEncoding.Probing catch // Default parsing { if (subtitle.Contains(".")) // skip the comment, keep the subtitle - description = String.Join(".", subtitle.Split('.'), 1, subtitle.Split('.').Length - 1).Trim(); // skip the first + description = string.Join(".", subtitle.Split('.'), 1, subtitle.Split('.').Length - 1).Trim(); // skip the first else description = subtitle.Trim(); // Clean up whitespaces and save it } diff --git a/MediaBrowser.MediaEncoding/Properties/AssemblyInfo.cs b/MediaBrowser.MediaEncoding/Properties/AssemblyInfo.cs index 53f4eb403..6ecdf89bc 100644 --- a/MediaBrowser.MediaEncoding/Properties/AssemblyInfo.cs +++ b/MediaBrowser.MediaEncoding/Properties/AssemblyInfo.cs @@ -1,33 +1,21 @@ -using System.Reflection; +using System.Reflection; +using System.Resources; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("MediaBrowser.MediaEncoding")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MediaBrowser.MediaEncoding")] -[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyCompany("Jellyfin Project")] +[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")] +[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] +[assembly: NeutralResourcesLanguage("en")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("05f49ab9-2a90-4332-9d41-7817a9cccd90")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")]
\ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs index 71fefba44..73df2b1e0 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles while ((line = reader.ReadLine()) != null) { cancellationToken.ThrowIfCancellationRequested(); - + if (string.IsNullOrWhiteSpace(line)) { continue; @@ -49,7 +49,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles RemoteNativeFormatting(subEvent); subEvent.Text = subEvent.Text.Replace("\\n", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase); - + subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase); trackEvents.Add(subEvent); diff --git a/MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs b/MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs index 2d29f29e3..1c1906de7 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs @@ -46,7 +46,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles _config.NamedConfigurationUpdating += _config_NamedConfigurationUpdating; Utilities.HttpClient = httpClient; - OpenSubtitles.SetUserAgent("mediabrowser.tv"); + OpenSubtitles.SetUserAgent("jellyfin"); } private const string PasswordHashPrefix = "h:"; @@ -121,7 +121,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (string.IsNullOrWhiteSpace(id)) { - throw new ArgumentNullException("id"); + throw new ArgumentNullException(nameof(id)); } var idParts = id.Split(new[] { '-' }, 3); diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs index 7ca8aa1fd..e9f9c6f58 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs @@ -43,7 +43,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { continue; } - + var time = Regex.Split(line, @"[\t ]*-->[\t ]*"); if (time.Length < 2) @@ -85,7 +85,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles TimeSpan span; return TimeSpan.TryParseExact(time, @"hh\:mm\:ss\.fff", _usCulture, out span) ? span.Ticks - : (TimeSpan.TryParseExact(time, @"hh\:mm\:ss\,fff", _usCulture, out span) + : (TimeSpan.TryParseExact(time, @"hh\:mm\:ss\,fff", _usCulture, out span) ? span.Ticks : 0); } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs index a2cee7793..022fca1c8 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs @@ -129,8 +129,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles } } } - } - + } + //if (header.Length > 0) //subtitle.Header = header.ToString(); diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index a1dc9b7d4..202623c8b 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -1,26 +1,25 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Entities; -using Microsoft.Extensions.Logging; -using MediaBrowser.Model.MediaInfo; -using MediaBrowser.Model.Serialization; -using System; +using System; using System.Collections.Concurrent; -using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.IO; using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Text; +using Microsoft.Extensions.Logging; namespace MediaBrowser.MediaEncoding.Subtitles { @@ -110,7 +109,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles if (endTimeTicks.HasValue) { - var endTime = endTimeTicks.Value; + long endTime = endTimeTicks.Value; track.TrackEvents = track.TrackEvents .TakeWhile(i => i.StartPositionTicks <= endTime) @@ -131,11 +130,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (item == null) { - throw new ArgumentNullException("item"); + throw new ArgumentNullException(nameof(item)); } if (string.IsNullOrWhiteSpace(mediaSourceId)) { - throw new ArgumentNullException("mediaSourceId"); + throw new ArgumentNullException(nameof(mediaSourceId)); } // TODO network path substition useful ? @@ -150,48 +149,51 @@ namespace MediaBrowser.MediaEncoding.Subtitles var subtitle = await GetSubtitleStream(mediaSource, subtitleStream, cancellationToken) .ConfigureAwait(false); - var inputFormat = subtitle.Item2; + var inputFormat = subtitle.format; var writer = TryGetWriter(outputFormat); // Return the original if we don't have any way of converting it if (writer == null) { - return subtitle.Item1; + return subtitle.stream; } // Return the original if the same format is being requested // Character encoding was already handled in GetSubtitleStream if (string.Equals(inputFormat, outputFormat, StringComparison.OrdinalIgnoreCase)) { - return subtitle.Item1; + return subtitle.stream; } - using (var stream = subtitle.Item1) + using (var stream = subtitle.stream) { - return ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, preserveOriginalTimestamps, cancellationToken); + return ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, preserveOriginalTimestamps, cancellationToken); } } - private async Task<Tuple<Stream, string>> GetSubtitleStream(MediaSourceInfo mediaSource, + private async Task<(Stream stream, string format)> GetSubtitleStream( + MediaSourceInfo mediaSource, MediaStream subtitleStream, CancellationToken cancellationToken) { - var inputFiles = new[] { mediaSource.Path }; + string[] inputFiles; - if (mediaSource.VideoType.HasValue) + if (mediaSource.VideoType.HasValue + && (mediaSource.VideoType.Value == VideoType.BluRay || mediaSource.VideoType.Value == VideoType.Dvd)) { - if (mediaSource.VideoType.Value == VideoType.BluRay || mediaSource.VideoType.Value == VideoType.Dvd) - { - var mediaSourceItem = (Video)_libraryManager.GetItemById(new Guid(mediaSource.Id)); - inputFiles = mediaSourceItem.GetPlayableStreamFileNames(_mediaEncoder).ToArray(); - } + var mediaSourceItem = (Video)_libraryManager.GetItemById(new Guid(mediaSource.Id)); + inputFiles = mediaSourceItem.GetPlayableStreamFileNames(_mediaEncoder); + } + else + { + inputFiles = new[] { mediaSource.Path }; } var fileInfo = await GetReadableFile(mediaSource.Path, inputFiles, mediaSource.Protocol, subtitleStream, cancellationToken).ConfigureAwait(false); - var stream = await GetSubtitleStream(fileInfo.Item1, subtitleStream.Language, fileInfo.Item2, fileInfo.Item4, cancellationToken).ConfigureAwait(false); + var stream = await GetSubtitleStream(fileInfo.Path, subtitleStream.Language, fileInfo.Protocol, fileInfo.IsExternal, cancellationToken).ConfigureAwait(false); - return new Tuple<Stream, string>(stream, fileInfo.Item3); + return (stream, fileInfo.Format); } private async Task<Stream> GetSubtitleStream(string path, string language, MediaProtocol protocol, bool requiresCharset, CancellationToken cancellationToken) @@ -206,15 +208,13 @@ namespace MediaBrowser.MediaEncoding.Subtitles if (!string.IsNullOrEmpty(charset)) { using (var inputStream = new MemoryStream(bytes)) + using (var reader = new StreamReader(inputStream, _textEncoding.GetEncodingFromCharset(charset))) { - using (var reader = new StreamReader(inputStream, _textEncoding.GetEncodingFromCharset(charset))) - { - var text = await reader.ReadToEndAsync().ConfigureAwait(false); + var text = await reader.ReadToEndAsync().ConfigureAwait(false); - bytes = Encoding.UTF8.GetBytes(text); + bytes = Encoding.UTF8.GetBytes(text); - return new MemoryStream(bytes); - } + return new MemoryStream(bytes); } } } @@ -222,7 +222,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles return _fileSystem.OpenRead(path); } - private async Task<Tuple<string, MediaProtocol, string, bool>> GetReadableFile(string mediaPath, + private async Task<SubtitleInfo> GetReadableFile( + string mediaPath, string[] inputFiles, MediaProtocol protocol, MediaStream subtitleStream, @@ -237,30 +238,30 @@ namespace MediaBrowser.MediaEncoding.Subtitles string.Equals(subtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase) || string.Equals(subtitleStream.Codec, "srt", StringComparison.OrdinalIgnoreCase)) { - // Extract + // Extract outputCodec = "copy"; outputFormat = subtitleStream.Codec; } else if (string.Equals(subtitleStream.Codec, "subrip", StringComparison.OrdinalIgnoreCase)) { - // Extract + // Extract outputCodec = "copy"; outputFormat = "srt"; } else { - // Extract + // Extract outputCodec = "srt"; outputFormat = "srt"; } - // Extract + // Extract var outputPath = GetSubtitleCachePath(mediaPath, protocol, subtitleStream.Index, "." + outputFormat); await ExtractTextSubtitle(inputFiles, protocol, subtitleStream.Index, outputCodec, outputPath, cancellationToken) .ConfigureAwait(false); - return new Tuple<string, MediaProtocol, string, bool>(outputPath, MediaProtocol.File, outputFormat, false); + return new SubtitleInfo(outputPath, MediaProtocol.File, outputFormat, false); } var currentFormat = (Path.GetExtension(subtitleStream.Path) ?? subtitleStream.Codec) @@ -268,22 +269,38 @@ namespace MediaBrowser.MediaEncoding.Subtitles if (GetReader(currentFormat, false) == null) { - // Convert + // Convert var outputPath = GetSubtitleCachePath(mediaPath, protocol, subtitleStream.Index, ".srt"); await ConvertTextSubtitleToSrt(subtitleStream.Path, subtitleStream.Language, protocol, outputPath, cancellationToken).ConfigureAwait(false); - return new Tuple<string, MediaProtocol, string, bool>(outputPath, MediaProtocol.File, "srt", true); + return new SubtitleInfo(outputPath, MediaProtocol.File, "srt", true); + } + + return new SubtitleInfo(subtitleStream.Path, protocol, currentFormat, true); + } + + private struct SubtitleInfo + { + public SubtitleInfo(string path, MediaProtocol protocol, string format, bool isExternal) + { + Path = path; + Protocol = protocol; + Format = format; + IsExternal = isExternal; } - return new Tuple<string, MediaProtocol, string, bool>(subtitleStream.Path, protocol, currentFormat, true); + public string Path { get; set; } + public MediaProtocol Protocol { get; set; } + public string Format { get; set; } + public bool IsExternal { get; set; } } private ISubtitleParser GetReader(string format, bool throwIfMissing) { if (string.IsNullOrEmpty(format)) { - throw new ArgumentNullException("format"); + throw new ArgumentNullException(nameof(format)); } if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase)) @@ -311,7 +328,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (string.IsNullOrEmpty(format)) { - throw new ArgumentNullException("format"); + throw new ArgumentNullException(nameof(format)); } if (string.Equals(format, "json", StringComparison.OrdinalIgnoreCase)) @@ -406,12 +423,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (string.IsNullOrEmpty(inputPath)) { - throw new ArgumentNullException("inputPath"); + throw new ArgumentNullException(nameof(inputPath)); } if (string.IsNullOrEmpty(outputPath)) { - throw new ArgumentNullException("outputPath"); + throw new ArgumentNullException(nameof(outputPath)); } _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(outputPath)); @@ -482,7 +499,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } catch (IOException ex) { - _logger.LogError(ex, "Error deleting converted subtitle {0}", outputPath); + _logger.LogError(ex, "Error deleting converted subtitle {Path}", outputPath); } } } @@ -493,7 +510,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles if (failed) { - var msg = string.Format("ffmpeg subtitle conversion failed for {0}", inputPath); + var msg = string.Format("ffmpeg subtitle conversion failed for {Path}", inputPath); _logger.LogError(msg); @@ -501,7 +518,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } await SetAssFont(outputPath).ConfigureAwait(false); - _logger.LogInformation("ffmpeg subtitle conversion succeeded for {0}", inputPath); + _logger.LogInformation("ffmpeg subtitle conversion succeeded for {Path}", inputPath); } /// <summary> @@ -515,8 +532,13 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentException">Must use inputPath list overload</exception> - private async Task ExtractTextSubtitle(string[] inputFiles, MediaProtocol protocol, int subtitleStreamIndex, - string outputCodec, string outputPath, CancellationToken cancellationToken) + private async Task ExtractTextSubtitle( + string[] inputFiles, + MediaProtocol protocol, + int subtitleStreamIndex, + string outputCodec, + string outputPath, + CancellationToken cancellationToken) { var semaphore = GetLock(outputPath); @@ -535,17 +557,21 @@ namespace MediaBrowser.MediaEncoding.Subtitles } } - private async Task ExtractTextSubtitleInternal(string inputPath, int subtitleStreamIndex, - string outputCodec, string outputPath, CancellationToken cancellationToken) + private async Task ExtractTextSubtitleInternal( + string inputPath, + int subtitleStreamIndex, + string outputCodec, + string outputPath, + CancellationToken cancellationToken) { if (string.IsNullOrEmpty(inputPath)) { - throw new ArgumentNullException("inputPath"); + throw new ArgumentNullException(nameof(inputPath)); } if (string.IsNullOrEmpty(outputPath)) { - throw new ArgumentNullException("outputPath"); + throw new ArgumentNullException(nameof(outputPath)); } _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(outputPath)); @@ -564,7 +590,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles ErrorDialog = false }); - _logger.LogInformation("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); + _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); try { @@ -583,7 +609,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { try { - _logger.LogInformation("Killing ffmpeg subtitle extraction process"); + _logger.LogWarning("Killing ffmpeg subtitle extraction process"); process.Kill(); } @@ -605,7 +631,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles try { - _logger.LogInformation("Deleting extracted subtitle due to failure: {0}", outputPath); + _logger.LogWarning("Deleting extracted subtitle due to failure: {Path}", outputPath); _fileSystem.DeleteFile(outputPath); } catch (FileNotFoundException) @@ -614,7 +640,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } catch (IOException ex) { - _logger.LogError(ex, "Error deleting extracted subtitle {0}", outputPath); + _logger.LogError(ex, "Error deleting extracted subtitle {Path}", outputPath); } } else if (!_fileSystem.FileExists(outputPath)) @@ -624,7 +650,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles if (failed) { - var msg = string.Format("ffmpeg subtitle extraction failed for {0} to {1}", inputPath, outputPath); + var msg = $"ffmpeg subtitle extraction failed for {inputPath} to {outputPath}"; _logger.LogError(msg); @@ -632,7 +658,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } else { - var msg = string.Format("ffmpeg subtitle extraction completed for {0} to {1}", inputPath, outputPath); + var msg = $"ffmpeg subtitle extraction completed for {inputPath} to {outputPath}"; _logger.LogInformation(msg); } @@ -650,19 +676,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// <returns>Task.</returns> private async Task SetAssFont(string file) { - _logger.LogInformation("Setting ass font within {0}", file); + _logger.LogInformation("Setting ass font within {File}", file); string text; Encoding encoding; using (var fileStream = _fileSystem.OpenRead(file)) + using (var reader = new StreamReader(fileStream, true)) { - using (var reader = new StreamReader(fileStream, true)) - { - encoding = reader.CurrentEncoding; + encoding = reader.CurrentEncoding; - text = await reader.ReadToEndAsync().ConfigureAwait(false); - } + text = await reader.ReadToEndAsync().ConfigureAwait(false); } var newText = text.Replace(",Arial,", ",Arial Unicode MS,"); @@ -707,7 +731,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles var charset = _textEncoding.GetDetectedEncodingName(bytes, bytes.Length, language, true); - _logger.LogDebug("charset {0} detected for {1}", charset ?? "null", path); + _logger.LogDebug("charset {0} detected for {Path}", charset ?? "null", path); return charset; } @@ -716,18 +740,18 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (protocol == MediaProtocol.Http) { - HttpRequestOptions opts = new HttpRequestOptions(); - opts.Url = path; - opts.CancellationToken = cancellationToken; + HttpRequestOptions opts = new HttpRequestOptions() + { + Url = path, + CancellationToken = cancellationToken + }; using (var file = await _httpClient.Get(opts).ConfigureAwait(false)) + using (var memoryStream = new MemoryStream()) { - using (var memoryStream = new MemoryStream()) - { - await file.CopyToAsync(memoryStream).ConfigureAwait(false); - memoryStream.Position = 0; + await file.CopyToAsync(memoryStream).ConfigureAwait(false); + memoryStream.Position = 0; - return memoryStream.ToArray(); - } + return memoryStream.ToArray(); } } if (protocol == MediaProtocol.File) @@ -735,8 +759,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles return _fileSystem.ReadAllBytes(path); } - throw new ArgumentOutOfRangeException("protocol"); + throw new ArgumentOutOfRangeException(nameof(protocol)); } - } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs b/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs index c32005f89..f0cf3b31a 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs @@ -45,7 +45,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles writer.WriteLine("</div>"); writer.WriteLine("</body>"); - + writer.WriteLine("</tt>"); } } |
