aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.MediaEncoding
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.MediaEncoding')
-rw-r--r--MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs1
-rw-r--r--MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs8
-rw-r--r--MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs16
-rw-r--r--MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs15
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs101
-rw-r--r--MediaBrowser.MediaEncoding/FfmpegException.cs39
-rw-r--r--MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj8
-rw-r--r--MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs15
-rw-r--r--MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Probing/MediaChapter.cs1
-rw-r--r--MediaBrowser.MediaEncoding/Probing/MediaFormatInfo.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs3
-rw-r--r--MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs171
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/AssParser.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs10
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs75
20 files changed, 225 insertions, 252 deletions
diff --git a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs
index e8aeabf9d..a0ec3bd90 100644
--- a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs
+++ b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs
@@ -1,3 +1,4 @@
+#nullable disable
#pragma warning disable CS1591
using System;
diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs
index 4a54b677d..e86e518be 100644
--- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs
+++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs
@@ -9,9 +9,9 @@ namespace MediaBrowser.MediaEncoding.BdInfo
{
public class BdInfoDirectoryInfo : IDirectoryInfo
{
- private readonly IFileSystem _fileSystem = null;
+ private readonly IFileSystem _fileSystem;
- private readonly FileSystemMetadata _impl = null;
+ private readonly FileSystemMetadata _impl;
public BdInfoDirectoryInfo(IFileSystem fileSystem, string path)
{
@@ -29,7 +29,7 @@ namespace MediaBrowser.MediaEncoding.BdInfo
public string FullName => _impl.FullName;
- public IDirectoryInfo Parent
+ public IDirectoryInfo? Parent
{
get
{
@@ -71,7 +71,7 @@ namespace MediaBrowser.MediaEncoding.BdInfo
_impl.FullName,
new[] { searchPattern },
false,
- searchOption.HasFlag(System.IO.SearchOption.AllDirectories)).ToArray(),
+ (searchOption & System.IO.SearchOption.AllDirectories) == System.IO.SearchOption.AllDirectories).ToArray(),
x => new BdInfoFileInfo(x));
}
diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs
index 9108d9649..6ebaa4fff 100644
--- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs
+++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs
@@ -61,33 +61,25 @@ namespace MediaBrowser.MediaEncoding.BdInfo
foreach (var stream in playlist.SortedStreams)
{
- var videoStream = stream as TSVideoStream;
-
- if (videoStream != null)
+ if (stream is TSVideoStream videoStream)
{
AddVideoStream(mediaStreams, videoStream);
continue;
}
- var audioStream = stream as TSAudioStream;
-
- if (audioStream != null)
+ if (stream is TSAudioStream audioStream)
{
AddAudioStream(mediaStreams, audioStream);
continue;
}
- var textStream = stream as TSTextStream;
-
- if (textStream != null)
+ if (stream is TSTextStream textStream)
{
AddSubtitleStream(mediaStreams, textStream);
continue;
}
- var graphicsStream = stream as TSGraphicsStream;
-
- if (graphicsStream != null)
+ if (stream is TSGraphicsStream graphicsStream)
{
AddSubtitleStream(mediaStreams, graphicsStream);
}
diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs
index 0a8af8e9c..41143c259 100644
--- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs
+++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs
@@ -7,7 +7,7 @@ namespace MediaBrowser.MediaEncoding.BdInfo
{
public class BdInfoFileInfo : BDInfo.IO.IFileInfo
{
- private FileSystemMetadata _impl = null;
+ private FileSystemMetadata _impl;
public BdInfoFileInfo(FileSystemMetadata impl)
{
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
index 9e2417603..f782e65bd 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -121,11 +121,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
// When changing this, also change the minimum library versions in _ffmpegMinimumLibraryVersions
public static Version MinVersion { get; } = new Version(4, 0);
- public static Version MaxVersion { get; } = null;
+ public static Version? MaxVersion { get; } = null;
public bool ValidateVersion()
{
- string output = null;
+ string output;
try
{
output = GetProcessOutput(_encoderPath, "-version");
@@ -133,6 +133,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
catch (Exception ex)
{
_logger.LogError(ex, "Error validating encoder");
+ return false;
}
if (string.IsNullOrWhiteSpace(output))
@@ -207,7 +208,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary>
/// <param name="output">The output from "ffmpeg -version".</param>
/// <returns>The FFmpeg version.</returns>
- internal Version GetFFmpegVersion(string output)
+ internal Version? GetFFmpegVersion(string output)
{
// For pre-built binaries the FFmpeg version should be mentioned at the very start of the output
var match = Regex.Match(output, @"^ffmpeg version n?((?:[0-9]+\.?)+)");
@@ -275,7 +276,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
private IEnumerable<string> GetHwaccelTypes()
{
- string output = null;
+ string? output = null;
try
{
output = GetProcessOutput(_encoderPath, "-hwaccels");
@@ -303,7 +304,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
return false;
}
- string output = null;
+ string output;
try
{
output = GetProcessOutput(_encoderPath, "-h filter=" + filter);
@@ -311,6 +312,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
catch (Exception ex)
{
_logger.LogError(ex, "Error detecting the given filter");
+ return false;
}
if (output.Contains("Filter " + filter, StringComparison.Ordinal))
@@ -331,7 +333,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
private IEnumerable<string> GetCodecs(Codec codec)
{
string codecstr = codec == Codec.Encoder ? "encoders" : "decoders";
- string output = null;
+ string output;
try
{
output = GetProcessOutput(_encoderPath, "-" + codecstr);
@@ -339,6 +341,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
catch (Exception ex)
{
_logger.LogError(ex, "Error detecting available {Codec}", codecstr);
+ return Enumerable.Empty<string>();
}
if (string.IsNullOrWhiteSpace(output))
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index a52019384..cdb778bf2 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -1,3 +1,4 @@
+#nullable disable
#pragma warning disable CS1591
using System;
@@ -16,7 +17,6 @@ using MediaBrowser.Common.Json;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.MediaEncoding.Probing;
-using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -53,7 +53,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly IServerConfigurationManager _configurationManager;
private readonly IFileSystem _fileSystem;
private readonly ILocalizationManager _localization;
- private readonly Lazy<EncodingHelper> _encodingHelperFactory;
private readonly string _startupOptionFFmpegPath;
private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(2, 2);
@@ -77,16 +76,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
IServerConfigurationManager configurationManager,
IFileSystem fileSystem,
ILocalizationManager localization,
- Lazy<EncodingHelper> encodingHelperFactory,
IConfiguration config)
{
_logger = logger;
_configurationManager = configurationManager;
_fileSystem = fileSystem;
_localization = localization;
- _encodingHelperFactory = encodingHelperFactory;
_startupOptionFFmpegPath = config.GetValue<string>(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? string.Empty;
- _jsonSerializerOptions = JsonDefaults.GetOptions();
+ _jsonSerializerOptions = JsonDefaults.Options;
}
/// <inheritdoc />
@@ -370,7 +367,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
public string GetInputArgument(string inputFile, MediaSourceInfo mediaSource)
{
var prefix = "file";
- if (mediaSource.VideoType == VideoType.BluRay || mediaSource.VideoType == VideoType.Iso)
+ if (mediaSource.VideoType == VideoType.BluRay)
{
prefix = "bluray";
}
@@ -448,7 +445,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (result == null || (result.Streams == null && result.Format == null))
{
- throw new Exception("ffprobe failed - streams and format are both null.");
+ throw new FfmpegException("ffprobe failed - streams and format are both null.");
}
if (result.Streams != null)
@@ -571,32 +568,18 @@ namespace MediaBrowser.MediaEncoding.Encoder
// apply some filters to thumbnail extracted below (below) crop any black lines that we made and get the correct ar.
// This filter chain may have adverse effects on recorded tv thumbnails if ar changes during presentation ex. commercials @ diff ar
- var vf = string.Empty;
-
- if (threedFormat.HasValue)
+ var vf = threedFormat switch
{
- switch (threedFormat.Value)
- {
- case Video3DFormat.HalfSideBySide:
- vf = "-vf crop=iw/2:ih:0:0,scale=(iw*2):ih,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1";
- // hsbs crop width in half,scale to correct size, set the display aspect,crop out any black bars we may have made. Work out the correct height based on the display aspect it will maintain the aspect where -1 in this case (3d) may not.
- break;
- case Video3DFormat.FullSideBySide:
- vf = "-vf crop=iw/2:ih:0:0,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1";
- // fsbs crop width in half,set the display aspect,crop out any black bars we may have made
- break;
- case Video3DFormat.HalfTopAndBottom:
- vf = "-vf crop=iw:ih/2:0:0,scale=(iw*2):ih),setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1";
- // htab crop heigh in half,scale to correct size, set the display aspect,crop out any black bars we may have made
- break;
- case Video3DFormat.FullTopAndBottom:
- vf = "-vf crop=iw:ih/2:0:0,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1";
- // ftab crop heigt in half, set the display aspect,crop out any black bars we may have made
- break;
- default:
- break;
- }
- }
+ // hsbs crop width in half,scale to correct size, set the display aspect,crop out any black bars we may have made. Work out the correct height based on the display aspect it will maintain the aspect where -1 in this case (3d) may not.
+ Video3DFormat.HalfSideBySide => "-vf crop=iw/2:ih:0:0,scale=(iw*2):ih,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1",
+ // fsbs crop width in half,set the display aspect,crop out any black bars we may have made
+ Video3DFormat.FullSideBySide => "-vf crop=iw/2:ih:0:0,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1",
+ // htab crop heigh in half,scale to correct size, set the display aspect,crop out any black bars we may have made
+ Video3DFormat.HalfTopAndBottom => "-vf crop=iw:ih/2:0:0,scale=(iw*2):ih),setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1",
+ // ftab crop heigt in half, set the display aspect,crop out any black bars we may have made
+ Video3DFormat.FullTopAndBottom => "-vf crop=iw:ih/2:0:0,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1",
+ _ => string.Empty
+ };
var mapArg = imageStreamIndex.HasValue ? (" -map 0:v:" + imageStreamIndex.Value.ToString(CultureInfo.InvariantCulture)) : string.Empty;
@@ -604,7 +587,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (enableHdrExtraction)
{
string tonemapFilters = "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0:peak=100,zscale=t=bt709:m=bt709,format=yuv420p";
- if (string.IsNullOrEmpty(vf))
+ if (vf.Length == 0)
{
vf = "-vf " + tonemapFilters;
}
@@ -633,35 +616,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
var args = string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads {4} -v quiet -vframes 1 {2} -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, threads);
- var probeSizeArgument = string.Empty;
- var analyzeDurationArgument = string.Empty;
-
- if (!string.IsNullOrWhiteSpace(probeSizeArgument))
- {
- args = probeSizeArgument + " " + args;
- }
-
- if (!string.IsNullOrWhiteSpace(analyzeDurationArgument))
- {
- args = analyzeDurationArgument + " " + args;
- }
-
if (offset.HasValue)
{
args = string.Format(CultureInfo.InvariantCulture, "-ss {0} ", GetTimeParameter(offset.Value)) + args;
}
- if (videoStream != null)
- {
- /* fix
- var decoder = encodinghelper.GetHardwareAcceleratedVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions());
- if (!string.IsNullOrWhiteSpace(decoder))
- {
- args = decoder + " " + args;
- }
- */
- }
-
if (!string.IsNullOrWhiteSpace(container))
{
var inputFormat = EncodingHelper.GetInputFormat(container);
@@ -723,7 +682,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
_logger.LogError(msg);
- throw new Exception(msg);
+ throw new FfmpegException(msg);
}
return tempExtractPath;
@@ -770,30 +729,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
var args = string.Format(CultureInfo.InvariantCulture, "-i {0} -threads {3} -v quiet {2} -f image2 \"{1}\"", inputArgument, outputPath, vf, threads);
- var probeSizeArgument = string.Empty;
- var analyzeDurationArgument = string.Empty;
-
- if (!string.IsNullOrWhiteSpace(probeSizeArgument))
- {
- args = probeSizeArgument + " " + args;
- }
-
- if (!string.IsNullOrWhiteSpace(analyzeDurationArgument))
- {
- args = analyzeDurationArgument + " " + args;
- }
-
- if (videoStream != null)
- {
- /* fix
- var decoder = encodinghelper.GetHardwareAcceleratedVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions());
- if (!string.IsNullOrWhiteSpace(decoder))
- {
- args = decoder + " " + args;
- }
- */
- }
-
if (!string.IsNullOrWhiteSpace(container))
{
var inputFormat = EncodingHelper.GetInputFormat(container);
@@ -872,7 +807,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
_logger.LogError(msg);
- throw new Exception(msg);
+ throw new FfmpegException(msg);
}
}
}
diff --git a/MediaBrowser.MediaEncoding/FfmpegException.cs b/MediaBrowser.MediaEncoding/FfmpegException.cs
new file mode 100644
index 000000000..1697fd33a
--- /dev/null
+++ b/MediaBrowser.MediaEncoding/FfmpegException.cs
@@ -0,0 +1,39 @@
+using System;
+
+namespace MediaBrowser.MediaEncoding
+{
+ /// <summary>
+ /// Represents errors that occur during interaction with FFmpeg.
+ /// </summary>
+ public class FfmpegException : Exception
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FfmpegException"/> class.
+ /// </summary>
+ public FfmpegException()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FfmpegException"/> class with a specified error message.
+ /// </summary>
+ /// <param name="message">The message that describes the error.</param>
+ public FfmpegException(string message) : base(message)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FfmpegException"/> class with a specified error message and a
+ /// reference to the inner exception that is the cause of this exception.
+ /// </summary>
+ /// <param name="message">The error message that explains the reason for the exception.</param>
+ /// <param name="innerException">
+ /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if
+ /// no inner exception is specified.
+ /// </param>
+ public FfmpegException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+ }
+}
diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
index 3d6b4f98a..7733e715f 100644
--- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
+++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
@@ -10,6 +10,9 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ <Nullable>enable</Nullable>
+ <AnalysisMode>AllEnabledByDefault</AnalysisMode>
+ <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
@@ -30,13 +33,8 @@
<PackageReference Include="UTF.Unknown" Version="2.3.0" />
</ItemGroup>
- <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
- <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
-
<!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
- <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
diff --git a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
index b2d4db894..1fa90bb21 100644
--- a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
+++ b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
@@ -1,5 +1,8 @@
+#nullable disable
+
using System;
using System.Collections.Generic;
+using System.Globalization;
namespace MediaBrowser.MediaEncoding.Probing
{
@@ -85,12 +88,14 @@ namespace MediaBrowser.MediaEncoding.Probing
{
var val = GetDictionaryValue(tags, key);
- if (!string.IsNullOrEmpty(val))
+ if (string.IsNullOrEmpty(val))
{
- if (DateTime.TryParse(val, out var i))
- {
- return i.ToUniversalTime();
- }
+ return null;
+ }
+
+ if (DateTime.TryParse(val, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.AssumeUniversal, out var i))
+ {
+ return i.ToUniversalTime();
}
return null;
diff --git a/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs b/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs
index 0e319c1a8..d4d153b08 100644
--- a/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs
+++ b/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System.Collections.Generic;
using System.Text.Json.Serialization;
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs b/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs
index de062d06b..a1cef7a9f 100644
--- a/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs
+++ b/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs
@@ -1,3 +1,4 @@
+#nullable disable
#pragma warning disable CS1591
using System.Collections.Generic;
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaFormatInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaFormatInfo.cs
index 8af122ef9..d50da37b8 100644
--- a/MediaBrowser.MediaEncoding/Probing/MediaFormatInfo.cs
+++ b/MediaBrowser.MediaEncoding/Probing/MediaFormatInfo.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System.Collections.Generic;
using System.Text.Json.Serialization;
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
index 8a7c032c5..c9c8c34c2 100644
--- a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
+++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
@@ -1,6 +1,7 @@
+#nullable disable
+
using System.Collections.Generic;
using System.Text.Json.Serialization;
-using MediaBrowser.Common.Json.Converters;
namespace MediaBrowser.MediaEncoding.Probing
{
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index b9cb49cf2..bbff5daca 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -1,3 +1,4 @@
+#nullable disable
#pragma warning disable CS1591
using System;
@@ -29,7 +30,7 @@ namespace MediaBrowser.MediaEncoding.Probing
private readonly ILogger _logger;
private readonly ILocalizationManager _localization;
- private List<string> _splitWhiteList = null;
+ private string[] _splitWhiteList;
public ProbeResultNormalizer(ILogger logger, ILocalizationManager localization)
{
@@ -37,6 +38,8 @@ namespace MediaBrowser.MediaEncoding.Probing
_localization = localization;
}
+ private IReadOnlyList<string> SplitWhitelist => _splitWhiteList ??= new string[] { "AC/DC" };
+
public MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType? videoType, bool isAudio, string path, MediaProtocol protocol)
{
var info = new MediaInfo
@@ -57,7 +60,7 @@ namespace MediaBrowser.MediaEncoding.Probing
.Where(i => i.Type != MediaStreamType.Subtitle || !string.IsNullOrWhiteSpace(i.Codec))
.ToList();
- info.MediaAttachments = internalStreams.Select(s => GetMediaAttachment(s))
+ info.MediaAttachments = internalStreams.Select(GetMediaAttachment)
.Where(i => i != null)
.ToList();
@@ -121,18 +124,67 @@ namespace MediaBrowser.MediaEncoding.Probing
{
info.Name = title;
}
+ else
+ {
+ title = FFProbeHelpers.GetDictionaryValue(tags, "title-eng");
+ if (!string.IsNullOrWhiteSpace(title))
+ {
+ info.Name = title;
+ }
+ }
+
+ var titleSort = FFProbeHelpers.GetDictionaryValue(tags, "titlesort");
+ if (!string.IsNullOrWhiteSpace(titleSort))
+ {
+ info.ForcedSortName = titleSort;
+ }
info.IndexNumber = FFProbeHelpers.GetDictionaryNumericValue(tags, "episode_sort");
info.ParentIndexNumber = FFProbeHelpers.GetDictionaryNumericValue(tags, "season_number");
info.ShowName = FFProbeHelpers.GetDictionaryValue(tags, "show_name");
info.ProductionYear = FFProbeHelpers.GetDictionaryNumericValue(tags, "date");
- // Several different forms of retaildate
- info.PremiereDate = FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ??
+ // Several different forms of retail/premiere date
+ info.PremiereDate =
+ FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ??
FFProbeHelpers.GetDictionaryDateTime(tags, "retail date") ??
FFProbeHelpers.GetDictionaryDateTime(tags, "retail_date") ??
+ FFProbeHelpers.GetDictionaryDateTime(tags, "date_released") ??
FFProbeHelpers.GetDictionaryDateTime(tags, "date");
+ // Set common metadata for music (audio) and music videos (video)
+ info.Album = FFProbeHelpers.GetDictionaryValue(tags, "album");
+
+ var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists");
+
+ if (!string.IsNullOrWhiteSpace(artists))
+ {
+ info.Artists = SplitArtists(artists, new[] { '/', ';' }, false)
+ .DistinctNames()
+ .ToArray();
+ }
+ else
+ {
+ var artist = FFProbeHelpers.GetDictionaryValue(tags, "artist");
+ if (string.IsNullOrWhiteSpace(artist))
+ {
+ info.Artists = Array.Empty<string>();
+ }
+ else
+ {
+ info.Artists = SplitArtists(artist, _nameDelimiters, true)
+ .DistinctNames()
+ .ToArray();
+ }
+ }
+
+ // If we don't have a ProductionYear try and get it from PremiereDate
+ if (!info.ProductionYear.HasValue && info.PremiereDate.HasValue)
+ {
+ info.ProductionYear = info.PremiereDate.Value.Year;
+ }
+
+ // Set mediaType-specific metadata
if (isAudio)
{
SetAudioRuntimeTicks(data, info);
@@ -640,7 +692,7 @@ namespace MediaBrowser.MediaEncoding.Probing
}
// Filter out junk
- if (!string.IsNullOrWhiteSpace(streamInfo.CodecTagString) && streamInfo.CodecTagString.IndexOf("[0]", StringComparison.OrdinalIgnoreCase) == -1)
+ if (!string.IsNullOrWhiteSpace(streamInfo.CodecTagString) && !streamInfo.CodecTagString.Contains("[0]", StringComparison.OrdinalIgnoreCase))
{
stream.CodecTag = streamInfo.CodecTagString;
}
@@ -1075,13 +1127,13 @@ namespace MediaBrowser.MediaEncoding.Probing
private void SetAudioInfoFromTags(MediaInfo audio, Dictionary<string, string> tags)
{
- var peoples = new List<BaseItemPerson>();
+ var people = new List<BaseItemPerson>();
var composer = FFProbeHelpers.GetDictionaryValue(tags, "composer");
if (!string.IsNullOrWhiteSpace(composer))
{
foreach (var person in Split(composer, false))
{
- peoples.Add(new BaseItemPerson { Name = person, Type = PersonType.Composer });
+ people.Add(new BaseItemPerson { Name = person, Type = PersonType.Composer });
}
}
@@ -1090,7 +1142,7 @@ namespace MediaBrowser.MediaEncoding.Probing
{
foreach (var person in Split(conductor, false))
{
- peoples.Add(new BaseItemPerson { Name = person, Type = PersonType.Conductor });
+ people.Add(new BaseItemPerson { Name = person, Type = PersonType.Conductor });
}
}
@@ -1099,46 +1151,21 @@ namespace MediaBrowser.MediaEncoding.Probing
{
foreach (var person in Split(lyricist, false))
{
- peoples.Add(new BaseItemPerson { Name = person, Type = PersonType.Lyricist });
+ people.Add(new BaseItemPerson { Name = person, Type = PersonType.Lyricist });
}
}
// Check for writer some music is tagged that way as alternative to composer/lyricist
var writer = FFProbeHelpers.GetDictionaryValue(tags, "writer");
-
if (!string.IsNullOrWhiteSpace(writer))
{
foreach (var person in Split(writer, false))
{
- peoples.Add(new BaseItemPerson { Name = person, Type = PersonType.Writer });
+ people.Add(new BaseItemPerson { Name = person, Type = PersonType.Writer });
}
}
- audio.People = peoples.ToArray();
- audio.Album = FFProbeHelpers.GetDictionaryValue(tags, "album");
-
- var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists");
-
- if (!string.IsNullOrWhiteSpace(artists))
- {
- audio.Artists = SplitArtists(artists, new[] { '/', ';' }, false)
- .DistinctNames()
- .ToArray();
- }
- else
- {
- var artist = FFProbeHelpers.GetDictionaryValue(tags, "artist");
- if (string.IsNullOrWhiteSpace(artist))
- {
- audio.Artists = Array.Empty<string>();
- }
- else
- {
- audio.Artists = SplitArtists(artist, _nameDelimiters, true)
- .DistinctNames()
- .ToArray();
- }
- }
+ audio.People = people.ToArray();
var albumArtist = FFProbeHelpers.GetDictionaryValue(tags, "albumartist");
if (string.IsNullOrWhiteSpace(albumArtist))
@@ -1173,12 +1200,6 @@ namespace MediaBrowser.MediaEncoding.Probing
// Disc number
audio.ParentIndexNumber = GetDictionaryDiscValue(tags, "disc");
- // If we don't have a ProductionYear try and get it from PremiereDate
- if (audio.PremiereDate.HasValue && !audio.ProductionYear.HasValue)
- {
- audio.ProductionYear = audio.PremiereDate.Value.ToLocalTime().Year;
- }
-
// There's several values in tags may or may not be present
FetchStudios(audio, tags, "organization");
FetchStudios(audio, tags, "ensemble");
@@ -1186,43 +1207,28 @@ namespace MediaBrowser.MediaEncoding.Probing
FetchStudios(audio, tags, "label");
// These support mulitple values, but for now we only store the first.
- var mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id"));
- if (mb == null)
- {
- mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMARTISTID"));
- }
+ var mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id"))
+ ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMARTISTID"));
audio.SetProviderId(MetadataProvider.MusicBrainzAlbumArtist, mb);
- mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id"));
- if (mb == null)
- {
- mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ARTISTID"));
- }
+ mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id"))
+ ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ARTISTID"));
audio.SetProviderId(MetadataProvider.MusicBrainzArtist, mb);
- mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id"));
- if (mb == null)
- {
- mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMID"));
- }
+ mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id"))
+ ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMID"));
audio.SetProviderId(MetadataProvider.MusicBrainzAlbum, mb);
- mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id"));
- if (mb == null)
- {
- mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASEGROUPID"));
- }
+ mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id"))
+ ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASEGROUPID"));
audio.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, mb);
- mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id"));
- if (mb == null)
- {
- mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASETRACKID"));
- }
+ mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id"))
+ ?? GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASETRACKID"));
audio.SetProviderId(MetadataProvider.MusicBrainzTrack, mb);
}
@@ -1268,7 +1274,7 @@ namespace MediaBrowser.MediaEncoding.Probing
var artistsFound = new List<string>();
- foreach (var whitelistArtist in GetSplitWhitelist())
+ foreach (var whitelistArtist in SplitWhitelist)
{
var originalVal = val;
val = val.Replace(whitelistArtist, "|", StringComparison.OrdinalIgnoreCase);
@@ -1287,19 +1293,6 @@ namespace MediaBrowser.MediaEncoding.Probing
return artistsFound;
}
- private IEnumerable<string> GetSplitWhitelist()
- {
- if (_splitWhiteList == null)
- {
- _splitWhiteList = new List<string>
- {
- "AC/DC"
- };
- }
-
- return _splitWhiteList;
- }
-
/// <summary>
/// Gets the studios from the tags collection.
/// </summary>
@@ -1500,11 +1493,23 @@ namespace MediaBrowser.MediaEncoding.Probing
}
else
{
- throw new Exception(); // Switch to default parsing
+ // Switch to default parsing
+ if (subtitle.Contains('.', StringComparison.Ordinal))
+ {
+ // skip the comment, keep the subtitle
+ description = string.Join('.', subtitle.Split('.'), 1, subtitle.Split('.').Length - 1).Trim(); // skip the first
+ }
+ else
+ {
+ description = subtitle.Trim(); // Clean up whitespaces and save it
+ }
}
}
- catch // Default parsing
+ catch (Exception ex)
{
+ _logger.LogError(ex, "Error while parsing subtitle field");
+
+ // Default parsing
if (subtitle.Contains('.', StringComparison.Ordinal))
{
// skip the comment, keep the subtitle
diff --git a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
index 8219aa7b4..08ee5c72e 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using Microsoft.Extensions.Logging;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
diff --git a/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs b/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs
deleted file mode 100644
index dca5c1e8a..000000000
--- a/MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-#nullable enable
-#pragma warning disable CS1591
-
-namespace MediaBrowser.MediaEncoding.Subtitles
-{
- public static class ParserValues
- {
- public const string NewLine = "\r\n";
- }
-}
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs
index 19fb951dc..78d54ca51 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using Microsoft.Extensions.Logging;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
index 36dc2e01f..17c2ae40e 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using Microsoft.Extensions.Logging;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs
index 82ec6ca21..639a34d99 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System.Globalization;
using System.IO;
using System.Linq;
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index d19538730..608ebf443 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -25,7 +26,7 @@ using UtfUnknown;
namespace MediaBrowser.MediaEncoding.Subtitles
{
- public class SubtitleEncoder : ISubtitleEncoder
+ public sealed class SubtitleEncoder : ISubtitleEncoder
{
private readonly ILogger<SubtitleEncoder> _logger;
private readonly IApplicationPaths _appPaths;
@@ -71,8 +72,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
try
{
- var reader = GetReader(inputFormat, true);
-
+ var reader = GetReader(inputFormat);
var trackInfo = reader.Parse(stream, cancellationToken);
FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps);
@@ -139,10 +139,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
.ConfigureAwait(false);
var inputFormat = subtitle.format;
- var writer = TryGetWriter(outputFormat);
// Return the original if we don't have any way of converting it
- if (writer == null)
+ if (!TryGetWriter(outputFormat, out var writer))
{
return subtitle.stream;
}
@@ -239,7 +238,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var currentFormat = (Path.GetExtension(subtitleStream.Path) ?? subtitleStream.Codec)
.TrimStart('.');
- if (GetReader(currentFormat, false) == null)
+ if (TryGetReader(currentFormat, out _))
{
// Convert
var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, ".srt");
@@ -257,37 +256,41 @@ namespace MediaBrowser.MediaEncoding.Subtitles
return new SubtitleInfo(subtitleStream.Path, mediaSource.Protocol, currentFormat, true);
}
- private ISubtitleParser GetReader(string format, bool throwIfMissing)
+ private bool TryGetReader(string format, [NotNullWhen(true)] out ISubtitleParser? value)
{
- if (string.IsNullOrEmpty(format))
- {
- throw new ArgumentNullException(nameof(format));
- }
-
if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase))
{
- return new SrtParser(_logger);
+ value = new SrtParser(_logger);
+ return true;
}
if (string.Equals(format, SubtitleFormat.SSA, StringComparison.OrdinalIgnoreCase))
{
- return new SsaParser(_logger);
+ value = new SsaParser(_logger);
+ return true;
}
if (string.Equals(format, SubtitleFormat.ASS, StringComparison.OrdinalIgnoreCase))
{
- return new AssParser(_logger);
+ value = new AssParser(_logger);
+ return true;
}
- if (throwIfMissing)
+ value = null;
+ return false;
+ }
+
+ private ISubtitleParser GetReader(string format)
+ {
+ if (TryGetReader(format, out var reader))
{
- throw new ArgumentException("Unsupported format: " + format);
+ return reader;
}
- return null;
+ throw new ArgumentException("Unsupported format: " + format);
}
- private ISubtitleWriter TryGetWriter(string format)
+ private bool TryGetWriter(string format, [NotNullWhen(true)] out ISubtitleWriter? value)
{
if (string.IsNullOrEmpty(format))
{
@@ -296,32 +299,35 @@ namespace MediaBrowser.MediaEncoding.Subtitles
if (string.Equals(format, "json", StringComparison.OrdinalIgnoreCase))
{
- return new JsonWriter();
+ value = new JsonWriter();
+ return true;
}
if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase))
{
- return new SrtWriter();
+ value = new SrtWriter();
+ return true;
}
if (string.Equals(format, SubtitleFormat.VTT, StringComparison.OrdinalIgnoreCase))
{
- return new VttWriter();
+ value = new VttWriter();
+ return true;
}
if (string.Equals(format, SubtitleFormat.TTML, StringComparison.OrdinalIgnoreCase))
{
- return new TtmlWriter();
+ value = new TtmlWriter();
+ return true;
}
- return null;
+ value = null;
+ return false;
}
private ISubtitleWriter GetWriter(string format)
{
- var writer = TryGetWriter(format);
-
- if (writer != null)
+ if (TryGetWriter(format, out var writer))
{
return writer;
}
@@ -391,7 +397,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
throw new ArgumentNullException(nameof(outputPath));
}
- Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
+ Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)));
var encodingParam = await GetSubtitleFileCharacterSet(inputPath, language, mediaSource.Protocol, cancellationToken).ConfigureAwait(false);
@@ -484,7 +490,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
_logger.LogError("ffmpeg subtitle conversion failed for {Path}", inputPath);
- throw new Exception(
+ throw new FfmpegException(
string.Format(CultureInfo.InvariantCulture, "ffmpeg subtitle conversion failed for {0}", inputPath));
}
@@ -549,7 +555,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
throw new ArgumentNullException(nameof(outputPath));
}
- Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
+ Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)));
var processArgs = string.Format(
CultureInfo.InvariantCulture,
@@ -637,7 +643,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_logger.LogError(msg);
- throw new Exception(msg);
+ throw new FfmpegException(msg);
}
else
{
@@ -677,7 +683,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
if (!string.Equals(text, newText, StringComparison.Ordinal))
{
- using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))
+ // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
+ using (var fileStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None))
using (var writer = new StreamWriter(fileStream, encoding))
{
await writer.WriteAsync(newText.AsMemory(), cancellationToken).ConfigureAwait(false);
@@ -714,7 +721,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
using (var stream = await GetStream(path, protocol, cancellationToken).ConfigureAwait(false))
{
- var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName;
+ var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName ?? string.Empty;
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
if ((path.EndsWith(".ass", StringComparison.Ordinal) || path.EndsWith(".ssa", StringComparison.Ordinal) || path.EndsWith(".srt", StringComparison.Ordinal))
@@ -724,7 +731,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
charset = string.Empty;
}
- _logger.LogDebug("charset {0} detected for {Path}", charset ?? "null", path);
+ _logger.LogDebug("charset {0} detected for {Path}", charset, path);
return charset;
}